Skip to content

Commit 0793398

Browse files
David Mark Clementstargos
David Mark Clements
authored andcommitted
stream: add null push transform in async_iterator
when the readable side of a transform ends any for await loop on that transform stream should also complete. This fix prevents for await loop on a transform stream from hanging indefinitely. PR-URL: #28566 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 77bdbc5 commit 0793398

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lib/internal/streams/async_iterator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ const createReadableStreamAsyncIterator = (stream) => {
155155
});
156156
iterator[kLastPromise] = null;
157157

158-
finished(stream, (err) => {
158+
finished(stream, { writable: false }, (err) => {
159159
if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
160160
const reject = iterator[kLastReject];
161161
// Reject if we are waiting for data in the Promise returned by next() and

test/parallel/test-stream-readable-async-iterators.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const common = require('../common');
4-
const { Readable, PassThrough, pipeline } = require('stream');
4+
const { Readable, Transform, PassThrough, pipeline } = require('stream');
55
const assert = require('assert');
66

77
async function tests() {
@@ -396,6 +396,30 @@ async function tests() {
396396
}
397397
}
398398

399+
{
400+
console.log('readable side of a transform stream pushes null');
401+
const transform = new Transform({
402+
objectMode: true,
403+
transform: (chunk, enc, cb) => { cb(null, chunk); }
404+
});
405+
transform.push(0);
406+
transform.push(1);
407+
process.nextTick(() => {
408+
transform.push(null);
409+
});
410+
411+
const mustReach = [ common.mustCall(), common.mustCall() ];
412+
413+
const iter = transform[Symbol.asyncIterator]();
414+
assert.strictEqual((await iter.next()).value, 0);
415+
416+
for await (const d of iter) {
417+
assert.strictEqual(d, 1);
418+
mustReach[0]();
419+
}
420+
mustReach[1]();
421+
}
422+
399423
{
400424
console.log('all next promises must be resolved on end');
401425
const r = new Readable({

0 commit comments

Comments
 (0)