-
Notifications
You must be signed in to change notification settings - Fork 30k
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
Readable.pipe() behaves inconsistently resuming (or not) the source #41785
Comments
Probably 4793f165dc from #36563 to fix #36544 |
cc @ronag |
I think it makes sense not to resume a source if you currently can't (conceptually) take more data. Showing interest in data you can't consume is probably not good? I think the issue here is that even after the data is drained the source isn't resumed? |
I might be sleepy but I think it's a bug: const { Readable, Writable } = require('stream');
const readable = new Readable({
read() {
this.push('hello');
this.push('world');
this.push(null);
},
objectMode: true
});
let cb;
const writable = new Writable({
write(chunk, encoding, callback) {
// don't call callback, save for later
cb = callback;
},
highWaterMark: 1,
objectMode: true
});
writable.write('a');
console.log(writable.writableNeedDrain); // true
console.log(readable.isPaused()); // false
readable.pipe(writable);
console.log(readable.isPaused()); // true
cb();
console.log(readable.isPaused()); // true, but I'd expect it to be false |
Thanks for your prompt response and your input, @benjamingr
Yep, that might make sense. Although the previous behaviour (resuming it) would make sense as well. When you pipe a source is like adding a And what about to pause a source when you pipe it to a target that needs drain? I would say that in this case,
Definitely. I would expect pipe to handle that. |
I'm not sure I see a problem here. @benjamingr regarding your example,
I don't think it makes sense and also leads to potential memory leaks. The whole
PR welcome! |
And what about the fact that |
Do you have an example of this? |
Oh yeah that makes sense. I was sleepy after all :] |
Yep, @ronag, try the following code:
if you run this with a version of Nodejs >= v14.17.0, you will get something like
It looks like |
The flowing part of things work. It's just that Looks like a bug with the flowing/paused state of Readable. |
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: nodejs#41785
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: nodejs#41785
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: nodejs#41785 PR-URL: nodejs#41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: nodejs#41785 PR-URL: nodejs#41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Previously we would just resume "flowing" the stream without reseting the "paused" state. Fixes this by properly using pause/resume methods for .pipe. Fixes: #41785 PR-URL: #41848 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Version
14.17.0
Platform
Linux tufopad 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
stream
What steps will reproduce the bug?
Prior to v14.17.0 (versions <= v14.16.1), calling to
Readable.pipe()
would always resume the source if it had been previously paused. This behaviour was not documented, but it was consistent (it always happened). Since version 14.17.0 this behaviour changed and now it only resumes the source in some cases. If you run the following codewith version v14.16.1 you will get the following output
whereas with version v14.17.0 you get
In versions higher or equal to v14.17.0, the source is NOT resumed if the target needs a drain, and it does not resume even when the target drains. Furthermore, if the source wasn't paused,
Readable.pipe()
will pause it if the piped target needs to drain. This did not happen in versions <= v14.16.1.The fact that
Readable.pipe()
decides if it should pause or resume the source depending on the status of the target looks a bit inconsistent to me, and if not fixed, I believe that at least it would need to be documented.How often does it reproduce? Is there a required condition?
It always happens
What is the expected behavior?
It's a change of an undocumented behaviour, so it's hard for me to say what's the expected behaviour. The previous behaviour (resuming always the source) seemed a bit more consistent than the current
What do you see instead?
Read the experiment described in the "What steps will reproduce the bug?" section
Additional information
No response
The text was updated successfully, but these errors were encountered: