Skip to content

Commit 46f9638

Browse files
committed
stream: adjust src hwm when pipelining
1 parent 0a62026 commit 46f9638

File tree

3 files changed

+42
-11
lines changed

3 files changed

+42
-11
lines changed

lib/internal/streams/pipeline.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ function pipelineImpl(streams, callback, opts) {
294294
}
295295
} else if (isNodeStream(stream)) {
296296
if (isReadableNodeStream(ret)) {
297-
ret.pipe(stream);
297+
pipe(ret, stream);
298298

299299
// Compat. Before node v10.12.0 stdio used to throw an error so
300300
// pipe() did/does not end() stdio destinations.
@@ -321,4 +321,40 @@ function pipelineImpl(streams, callback, opts) {
321321
return ret;
322322
}
323323

324+
function pipe (src, dst) {
325+
const state = src._readableState;
326+
327+
if (typeof src.read !== 'function' && state) {
328+
src.pipe(dst);
329+
return;
330+
}
331+
332+
src
333+
.on('end', end)
334+
.on('readable', pump);
335+
dst
336+
.on('drain', pump);
337+
338+
function end () {
339+
dst.end();
340+
}
341+
342+
function pump () {
343+
if (dst.writableNeedDrain) {
344+
return;
345+
}
346+
347+
while (true) {
348+
state.highwaterMark = dst.writableHighwaterMark || dst.highwaterMark || null;
349+
350+
const chunk = src.read();
351+
if (chunk === null || !dst.write(chunk)) {
352+
return;
353+
}
354+
}
355+
}
356+
357+
process.nextTick(pump);
358+
}
359+
324360
module.exports = { pipelineImpl, pipeline };

test/parallel/test-stream-pipeline.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ const tsp = require('timers/promises');
2222
let finished = false;
2323
const processed = [];
2424
const expected = [
25-
Buffer.from('a'),
26-
Buffer.from('b'),
27-
Buffer.from('c'),
25+
Buffer.from('abc')
2826
];
2927

3028
const read = new Readable({
@@ -348,8 +346,7 @@ const tsp = require('timers/promises');
348346
};
349347

350348
const expected = [
351-
Buffer.from('hello'),
352-
Buffer.from('world'),
349+
Buffer.from('helloworld')
353350
];
354351

355352
const rs = new Readable({
@@ -985,7 +982,7 @@ const tsp = require('timers/promises');
985982
// Make sure 'close' before 'end' finishes without error
986983
// if readable has received eof.
987984
// Ref: https://github.com/nodejs/node/issues/29699
988-
const r = new Readable();
985+
const r = new Readable(({ read() {} }));
989986
const w = new Writable({
990987
write(chunk, encoding, cb) {
991988
cb();
@@ -1350,7 +1347,7 @@ const tsp = require('timers/promises');
13501347
});
13511348
const cb = common.mustCall((err) => {
13521349
assert.strictEqual(err.name, 'AbortError');
1353-
assert.strictEqual(res, '012345');
1350+
assert.strictEqual(res, '01234');
13541351
assert.strictEqual(w.destroyed, true);
13551352
assert.strictEqual(r.destroyed, true);
13561353
assert.strictEqual(pipelined.destroyed, true);

test/parallel/test-stream-promises.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ assert.strictEqual(finished, promisify(stream.finished));
2525
let finished = false;
2626
const processed = [];
2727
const expected = [
28-
Buffer.from('a'),
29-
Buffer.from('b'),
30-
Buffer.from('c'),
28+
Buffer.from('abc'),
3129
];
3230

3331
const read = new Readable({

0 commit comments

Comments
 (0)