stream: only increase awaitDrain once for each pipe destination#7292
stream: only increase awaitDrain once for each pipe destination#7292davedoesdev wants to merge 1 commit intonodejs:masterfrom davedoesdev:fix-7278
Conversation
There was a problem hiding this comment.
Just curious, would a Readable suffice here?
There was a problem hiding this comment.
Yes, but I'd have to set its _read to a nullop.
There was a problem hiding this comment.
I guess I could try doing the pushs in the _read.
There was a problem hiding this comment.
You could use new stream.Readable({read: () => {}}), but you can just leave it as a PassThrough if you prefer, I really was just curious. :)
|
Thanks, generally looking good! If you want, you can add an |
|
@addaleax thanks for the review. I'll add a commit addressing your comments but it won't be today now. |
|
okay I just updated the test |
There was a problem hiding this comment.
Is this line actually necessary? I think the test still tests what it’s supposed to test if you leave it out, because after the push() call here awaitDrain would already be 2… right?
There was a problem hiding this comment.
I wanted to test the effect (missing third buffer) rather than the cause.
In any case, awaitDrain isn't incremented until _write returns so it won't already be 2.
|
/cc @nodejs/streams I’d be kind of interested in knowing whether we generally guarantee that |
|
Also, I’m not sure why, but this branch seems to be based on a |
|
If |
|
No idea why it's a month old - only forked it yesterday. |
|
This branch is now rebased on latest |
|
@addaleax I removed the |
lib/_stream_readable.js
Outdated
There was a problem hiding this comment.
can you please add a comment on the reason for this variable?
There was a problem hiding this comment.
also we probably wanna move up the declaration of increasedAwaitDrain to before the ondata handler is attached. i'm pretty sure that might fire sync in some cases
|
Can you please format the commit message and squash the commits? |
|
This bug is "fixed" from |
Guard against the call to write() inside pipe's ondata pushing more data back onto the Readable, thus causing ondata to be called again. This is fine but results in awaitDrain being increased more than once. The problem with that is when the destination does drain, only a single 'drain' event is emitted, so awaitDrain in this case will never reach zero and we end up with a permanently paused stream.
|
@addaleax exactly. That means if you are depending on readable-stream@~2.0 it's fixed, and broken in readable-stream@~2.1 and readable-stream@^2.1. (I thought good first contribution was to tag possible future contributors, maybe I got it wrong) |
|
Should be squashed and reformatted now. |
|
LGTM |
|
CI: https://ci.nodejs.org/job/node-test-commit/3753/ |
|
LGTM |
|
Landed in b5175e8 Thanks for fixing this bug, @davedoesdev! I believe this is your first commit to core, if so, welcome on board and we hope you find other ways to contribute! |
Guard against the call to write() inside pipe's ondata pushing more data back onto the Readable, thus causing ondata to be called again. This is fine but results in awaitDrain being increased more than once. The problem with that is when the destination does drain, only a single 'drain' event is emitted, so awaitDrain in this case will never reach zero and we end up with a permanently paused stream. Fixes: #7278 PR-URL: #7292 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Guard against the call to write() inside pipe's ondata pushing more data back onto the Readable, thus causing ondata to be called again. This is fine but results in awaitDrain being increased more than once. The problem with that is when the destination does drain, only a single 'drain' event is emitted, so awaitDrain in this case will never reach zero and we end up with a permanently paused stream. Fixes: #7278 PR-URL: #7292 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
| // A readable stream which produces two buffers. | ||
| const bufs = [new Buffer(32 * 1024), new Buffer(33 * 1024)]; // above hwm | ||
| const readable = new stream.Readable({ | ||
| read: function() { |
There was a problem hiding this comment.
could have been read() { ^_^
Guard against the call to write() inside pipe's ondata pushing more data back onto the Readable, thus causing ondata to be called again. This is fine but results in awaitDrain being increased more than once. The problem with that is when the destination does drain, only a single 'drain' event is emitted, so awaitDrain in this case will never reach zero and we end up with a permanently paused stream. Fixes: #7278 PR-URL: #7292 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Guard against the call to write() inside pipe's ondata pushing more data back onto the Readable, thus causing ondata to be called again. This is fine but results in awaitDrain being increased more than once. The problem with that is when the destination does drain, only a single 'drain' event is emitted, so awaitDrain in this case will never reach zero and we end up with a permanently paused stream. Fixes: #7278 PR-URL: #7292 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Guard against the call to write() inside pipe's ondata pushing more data back onto the Readable, thus causing ondata to be called again. This is fine but results in awaitDrain being increased more than once. The problem with that is when the destination does drain, only a single 'drain' event is emitted, so awaitDrain in this case will never reach zero and we end up with a permanently paused stream. Fixes: #7278 PR-URL: #7292 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Checklist
make -j4 test(UNIX) orvcbuild test nosign(Windows) passesAffected core subsystem(s)
stream
Description of change
Guard against the call to
write()inside pipe'sondatapushing more databack onto the
Readable, thus causingondatato be called again.This is fine but results in
awaitDrainbeing increased more than once.The problem with that is when the destination does drain, only a single
drainevent is emitted, so
awaitDrainin this case will never reach zero and weend up with a permanently paused stream.
#7278