Skip to content
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: defer readable when sync #18515

Closed
wants to merge 3 commits into from

Conversation

mafintosh
Copy link
Member

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

stream

Fixes #18484 by not calling flow() when state.sync is set

@nodejs-github-bot nodejs-github-bot added the stream Issues and PRs related to the stream subsystem. label Feb 1, 2018
@mafintosh
Copy link
Member Author

/cc @mcollina @nodejs/streams

@mafintosh mafintosh changed the title Defer readable when sync stream: defer readable when sync Feb 1, 2018
@addaleax
Copy link
Member

addaleax commented Feb 2, 2018

Hi! :)

I can’t tell whether this patch is semantically correct on its own, but while looking into #18512, I checked and my patch at #18516 actually fixes both of the issues (at least going by the test commit provided here, which I’ve included in my PR). I’d be glad if you could take a look at that?

@mafintosh
Copy link
Member Author

@addaleax both PRs are valid. By #18512 you fix the symptom of this PR however the contract that no data will be emitted when flowing and the stream is paused is still broken. This PR fixes that.

The root cause here is that read() triggers _read which can trigger onEofChunk synchronously.
onEofChunk without this PR will trigger a flow() in the same tick causing data to be emitted under certain scenarios. However after this flow() the original read() call might trigger more data to be emitted even if the stream has been paused. This will break a lot userland code i fear :)

@addaleax
Copy link
Member

addaleax commented Feb 2, 2018

Thanks for the explanation, that was helpful!

By #18512 you fix the symptom of this PR however the contract that no data will be emitted when flowing and the stream is paused is still broken. This PR fixes that.

Not a blocker or anything, but could you add a test or similar code that doesn’t use .pipe() here?

@jasnell jasnell requested a review from mcollina February 2, 2018 16:47
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the additional test @addaleax required.

@mafintosh
Copy link
Member Author

mafintosh commented Feb 3, 2018

@addaleax @mcollina added a test that only uses pause/resume

@mcollina
Copy link
Member

mcollina commented Feb 3, 2018

@mafintosh
Copy link
Member Author

@mcollina fixed the other failing test by checking if there is any data in the buffer before nextTicking it

@mcollina
Copy link
Member

mcollina commented Feb 5, 2018

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mcollina
Copy link
Member

mcollina commented Feb 6, 2018

Landed as 563fff2.

@mcollina mcollina closed this Feb 6, 2018
mcollina pushed a commit that referenced this pull request Feb 6, 2018
PR-URL: #18515
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
addaleax added a commit to addaleax/node that referenced this pull request Feb 6, 2018
The complicated `awaitDrain` machinery can be made a bit
slimmer, and more correct, by just resetting the value
each time `stream.emit('data')` is called.

By resetting the value before emitting the data chunk, and
seeing whether any pipe destinations return `.write() === false`,
we always end up in a consistent state and don’t need to worry
about odd situations (like `dest.write(chunk)` emitting more data).

PR-URL: nodejs#18516
Fixes: nodejs#18484
Fixes: nodejs#18512
Refs: nodejs#18515
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
addaleax added a commit to addaleax/node that referenced this pull request Feb 7, 2018
This reverts commit 563fff2
as it was causing failures in CITGM with `dicer`.

Refs: nodejs#18515
addaleax pushed a commit to addaleax/node that referenced this pull request Feb 7, 2018
Refs: nodejs#18515
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
mcollina added a commit that referenced this pull request Feb 8, 2018
Fix a regression introduced by
#18515 that broke
the dicer module tests.

See: #18515

PR-URL: #18615
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
@MylesBorins
Copy link
Contributor

Should this be backported to v9.x-staging? If yes please follow the guide and raise a backport PR, if not let me know or add the dont-land-on label.

@mcollina
Copy link
Member

This should not be backported.

addaleax added a commit to addaleax/node that referenced this pull request Feb 27, 2018
The complicated `awaitDrain` machinery can be made a bit
slimmer, and more correct, by just resetting the value
each time `stream.emit('data')` is called.

By resetting the value before emitting the data chunk, and
seeing whether any pipe destinations return `.write() === false`,
we always end up in a consistent state and don’t need to worry
about odd situations (like `dest.write(chunk)` emitting more data).

PR-URL: nodejs#18516
Fixes: nodejs#18484
Fixes: nodejs#18512
Refs: nodejs#18515
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
PR-URL: nodejs#18515
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
The complicated `awaitDrain` machinery can be made a bit
slimmer, and more correct, by just resetting the value
each time `stream.emit('data')` is called.

By resetting the value before emitting the data chunk, and
seeing whether any pipe destinations return `.write() === false`,
we always end up in a consistent state and don’t need to worry
about odd situations (like `dest.write(chunk)` emitting more data).

PR-URL: nodejs#18516
Fixes: nodejs#18484
Fixes: nodejs#18512
Refs: nodejs#18515
Reviewed-By: Anatoli Papirovski <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Fix a regression introduced by
nodejs#18515 that broke
the dicer module tests.

See: nodejs#18515

PR-URL: nodejs#18615
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Colin Ihrig <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

stream: another missing end event
6 participants