Description
Version
>=17.0.0
(verified all the way up to the latest 19.7.0
)
Platform
Darwin watson-2.local 22.2.0 Darwin Kernel Version 22.2.0: Fri Nov 11 02:03:51 PST 2022; root:xnu-8792.61.2~4/RELEASE_ARM64_T6000 arm64
Subsystem
stream
What steps will reproduce the bug?
Run the following code and observe that the last assert throws because the stream still has a pending callback (because setImmediate
hasn't called cb
yet inside the streams write
function:
const { strict: assert } = require('node:assert');
const { Duplex, finished } = require('node:stream');
const stream = new Duplex({
write (chunk, enc, cb) {
setImmediate(cb);
}
});
stream.end('foo');
finished(stream, { readable: false }, (err) => {
console.log('Finished!');
assert.equal(err, undefined);
assert.equal(stream._writableState.pendingcb, 0);
});
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior?
I wouldn't expect stream.finished
to call its callback if there's still pending callbacks on the writable side.
What do you see instead?
I would expect stream.finished
to wait calling its callback until stream._writableState.pendingcb
is 0
.
Additional information
This is a follow up to issue #45281, which I had thought would fix the problem.
It's worth noting that this problem only occurs if it's a Duplex
or Transform
stream and only if finished
is passed readable: false
as an option.
Additionally, It might just be me who doesn't understand how stream.finished
is supposed to behave in this instance, in which case I'm just using it wrong. But if so, I'm not sure how to know when there's no more pending callbacks?