Skip to content

Commit 30e1f76

Browse files
jasnelladuh95
authored andcommitted
stream: reject unbounded at SyncShare construction
Signed-off-by: James M Snell <jasnell@gmail.com> Assisted-by: Opencode PR-URL: #66028 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Tim Perry <pimterry@gmail.com>
1 parent 0372056 commit 30e1f76

2 files changed

Lines changed: 50 additions & 10 deletions

File tree

lib/internal/streams/iter/share.js

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const {
5656
const {
5757
codes: {
5858
ERR_INVALID_ARG_TYPE,
59+
ERR_INVALID_ARG_VALUE,
5960
ERR_INVALID_RETURN_VALUE,
6061
ERR_OUT_OF_RANGE,
6162
},
@@ -588,11 +589,6 @@ class SyncShareImpl {
588589
throw new ERR_OUT_OF_RANGE(
589590
'buffered bytes', `< ${self.#options.budget}`,
590591
self.#bufferedBytes);
591-
case 'unbounded':
592-
throw new ERR_OUT_OF_RANGE(
593-
'buffered bytes', `< ${self.#options.budget} ` +
594-
'(unbounded not available in sync context)',
595-
self.#bufferedBytes);
596592
case 'drop-oldest':
597593
while (self.#bufferedBytes >= self.#options.budget &&
598594
self.#buffer.length > 0) {
@@ -609,9 +605,13 @@ class SyncShareImpl {
609605
self.#recomputeMinCursor();
610606
break;
611607
case 'drop-newest':
612-
state.detached = true;
613-
self.#deleteConsumer(state);
614-
return { __proto__: null, done: true, value: undefined };
608+
while (self.#bufferedBytes >= self.#options.budget &&
609+
!self.#sourceExhausted &&
610+
!self.#cancelled &&
611+
self.#sourceError === kNoShareError) {
612+
self.#pullFromSource(true);
613+
}
614+
break;
615615
}
616616
}
617617

@@ -694,7 +694,7 @@ class SyncShareImpl {
694694
this.cancel();
695695
}
696696

697-
#pullFromSource() {
697+
#pullFromSource(discard = false) {
698698
if (this.#sourceExhausted || this.#cancelled) return;
699699

700700
try {
@@ -704,7 +704,7 @@ class SyncShareImpl {
704704

705705
if (result.done) {
706706
this.#sourceExhausted = true;
707-
} else {
707+
} else if (!discard) {
708708
const entry = createBatchEntry(result.value);
709709
this.#buffer.push(entry);
710710
this.#bufferedBytes += entry.byteLength;
@@ -814,6 +814,11 @@ function shareSync(source, options = { __proto__: null }) {
814814
backpressure = 'strict',
815815
} = options;
816816
validateInteger(budget, 'options.budget', 16384);
817+
if (backpressure === 'unbounded') {
818+
throw new ERR_INVALID_ARG_VALUE(
819+
'options.backpressure', backpressure,
820+
'unbounded is not supported by shareSync()');
821+
}
817822

818823
const opts = {
819824
__proto__: null,

test/parallel/test-stream-iter-share-sync.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,39 @@ function testShareSyncSourceError() {
139139
}, { message: 'sync share boom' });
140140
}
141141

142+
function testShareSyncRejectsUnbounded() {
143+
assert.throws(
144+
() => shareSync(fromSync('data'), { backpressure: 'unbounded' }),
145+
{ code: 'ERR_INVALID_ARG_VALUE' },
146+
);
147+
}
148+
149+
function testShareSyncDropNewest() {
150+
let pulls = 0;
151+
function* source() {
152+
for (let i = 0; i < 3; i++) {
153+
pulls++;
154+
const chunk = new Uint8Array(16384);
155+
chunk[0] = i;
156+
yield [chunk];
157+
}
158+
}
159+
160+
const shared = shareSync(source(), {
161+
budget: 16384,
162+
backpressure: 'drop-newest',
163+
});
164+
const fast = shared.pull()[Symbol.iterator]();
165+
const slow = shared.pull()[Symbol.iterator]();
166+
167+
assert.strictEqual(fast.next().value[0][0], 0);
168+
assert.strictEqual(fast.next().done, true);
169+
assert.strictEqual(pulls, 3);
170+
171+
assert.strictEqual(slow.next().value[0][0], 0);
172+
assert.strictEqual(slow.next().done, true);
173+
}
174+
142175
// shareSync() accepts string source directly (normalized via fromSync())
143176
function testShareSyncStringSource() {
144177
const shared = shareSync('hello-sync-share');
@@ -154,5 +187,7 @@ Promise.all([
154187
testShareSyncCancelWithReason(),
155188
testShareSyncCancelWithFalsyReason(),
156189
testShareSyncSourceError(),
190+
testShareSyncRejectsUnbounded(),
191+
testShareSyncDropNewest(),
157192
testShareSyncStringSource(),
158193
]).then(common.mustCall());

0 commit comments

Comments
 (0)