stream: avoid retrying accepted pipeTo writes · nodejs/node@ec2666e · GitHub
Skip to content

Commit ec2666e

Browse files
trivikraduh95
authored andcommitted
stream: avoid retrying accepted pipeTo writes
PushWriter in block backpressure mode can return false from writeSync() and writevSync() after accepting data. Treat that false return as backpressure and wait for drain instead of retrying the same chunks asynchronously. Fixes: #63296 Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.5 PR-URL: #63297 Backport-PR-URL: #64675 Fixes: #63296 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
1 parent f63143f commit ec2666e

4 files changed

Lines changed: 76 additions & 3 deletions

File tree

lib/internal/streams/iter/pull.js

Lines changed: 32 additions & 0 deletions

lib/internal/streams/iter/push.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const {
3232

3333
const {
3434
drainableProtocol,
35+
kSyncWriteAcceptedOnFalse,
3536
} = require('internal/streams/iter/types');
3637

3738
const {
@@ -560,6 +561,10 @@ class PushWriter {
560561
return this.#queue.desiredSize;
561562
}
562563

564+
get [kSyncWriteAcceptedOnFalse]() {
565+
return this.#queue.backpressurePolicy === 'block';
566+
}
567+
563568
write(chunk, options) {
564569
if (!options?.signal && this.#queue.canWriteSync()) {
565570
const bytes = toUint8Array(chunk);
@@ -586,7 +591,8 @@ class PushWriter {
586591
writeSync(chunk) {
587592
const bytes = toUint8Array(chunk);
588593
const result = this.#queue.writeSync([bytes]);
589-
if (!result && this.#queue.backpressurePolicy === 'block') {
594+
if (!result && this.#queue.backpressurePolicy === 'block' &&
595+
this.#queue.desiredSize === 0) {
590596
// Block policy: force-enqueue and return false as backpressure signal.
591597
// Data IS accepted; false tells caller to slow down.
592598
this.#queue.forceEnqueue([bytes]);
@@ -601,7 +607,8 @@ class PushWriter {
601607
}
602608
const bytes = convertChunks(chunks);
603609
const result = this.#queue.writeSync(bytes);
604-
if (!result && this.#queue.backpressurePolicy === 'block') {
610+
if (!result && this.#queue.backpressurePolicy === 'block' &&
611+
this.#queue.desiredSize === 0) {
605612
this.#queue.forceEnqueue(bytes);
606613
return false;
607614
}

lib/internal/streams/iter/types.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,12 @@ const kValidatedTransform = Symbol('kValidatedTransform');
6464
*/
6565
const kValidatedSource = Symbol('kValidatedSource');
6666

67+
const kSyncWriteAcceptedOnFalse = Symbol('kSyncWriteAcceptedOnFalse');
68+
6769
module.exports = {
6870
broadcastProtocol,
6971
drainableProtocol,
72+
kSyncWriteAcceptedOnFalse,
7073
kValidatedSource,
7174
kValidatedTransform,
7275
shareProtocol,

test/parallel/test-stream-iter-pipeto-writev.js

Lines changed: 32 additions & 1 deletion

0 commit comments

Comments
 (0)