-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stream.finished calls callback when writable stream still has pending callbacks #46170
Comments
It really seems to be a bug! I'm troubleshooting it and will open a PR with the solution as soon as possible! |
I was digging a bit and it seems that when you call the If I put a setTimeout so the const { strict: assert } = require('node:assert')
const { Duplex, finished } = require('node:stream')
const stream = new Duplex({
write(chunk, enc, cb) {
setImmediate(cb)
}
})
setTimeout(() => stream.end('foo'), 200);
finished(stream, { readable: false }, (err) => {
console.log('Finished!')
assert.strictEqual(err, undefined)
assert.strictEqual(stream._writableState.pendingcb, 0)
}) Gonna ping the team here so we might discuss if this is actually the expected behavior EDIT: When looking at this piece and checking the cc @nodejs/streams |
This looks suspicious. Same problem on v19? |
I've tested from source and |
Fixes: nodejs#46170 PR-URL: nodejs#53438 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Fixes: nodejs#46170 PR-URL: nodejs#53438 Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Version
>=17.0.0
(verified all the way up to the latest19.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 calledcb
yet inside the streamswrite
function: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 untilstream._writableState.pendingcb
is0
.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
orTransform
stream and only iffinished
is passedreadable: 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?The text was updated successfully, but these errors were encountered: