- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 33.6k
stream: only increase awaitDrain once for each pipe destination #7292
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious, would a Readable suffice here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but I'd have to set its _read to a nullop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I could try doing the pushs in the _read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you please add a comment on the reason for this variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
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 <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
| // 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
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 <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
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 <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
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