Skip to content

Commit f7e2c54

Browse files
committed
stream: avoid unnecessary drain for sync stream
PR-URL: nodejs#50014
1 parent 85c09f1 commit f7e2c54

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

lib/internal/streams/writable.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const kWriteCb = 1 << 26;
108108
const kExpectWriteCb = 1 << 27;
109109
const kAfterWriteTickInfo = 1 << 28;
110110
const kAfterWritePending = 1 << 29;
111+
const kIsDuplex = 1 << 30;
111112

112113
// TODO(benjamingr) it is likely slower to do it this way than with free functions
113114
function makeBitMapDescriptor(bit) {
@@ -286,6 +287,7 @@ function WritableState(options, stream, isDuplex) {
286287

287288
if (options && options.objectMode) this.state |= kObjectMode;
288289
if (isDuplex && options && options.writableObjectMode) this.state |= kObjectMode;
290+
if (isDuplex) this.state |= kIsDuplex;
289291

290292
// The point at which write() starts returning false
291293
// Note: 0 is a valid value, means that we always return false if
@@ -513,13 +515,7 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
513515

514516
state.length += len;
515517

516-
// stream._write resets state.length
517-
const ret = state.length < state.highWaterMark;
518-
519-
// We must ensure that previous needDrain will not be reset to false.
520-
if (!ret) {
521-
state.state |= kNeedDrain;
522-
}
518+
const prevLen = state.length;
523519

524520
if ((state.state & (kWriting | kErrored | kCorked | kConstructed)) !== kConstructed) {
525521
state.buffered.push({ chunk, encoding, callback });
@@ -539,6 +535,16 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
539535
state.state &= ~kSync;
540536
}
541537

538+
const ret = (
539+
((state.state & kIsDuplex) === 0 || stream._readableState.ended !== true) ?
540+
state.length < state.highWaterMark :
541+
prevLen < state.highWaterMark
542+
);
543+
544+
if (!ret) {
545+
state.state |= kNeedDrain;
546+
}
547+
542548
// Return false if errored or destroyed in order to break
543549
// any synchronous while(stream.write(data)) loops.
544550
return ret && (state.state & (kDestroyed | kErrored)) === 0;

0 commit comments

Comments
 (0)