Skip to content

stream: always defer 'readable' with nextTick - #17979

Closed
mcollina wants to merge 3 commits into
nodejs:masterfrom
mcollina:stream-next-tick-readable
Closed

stream: always defer 'readable' with nextTick#17979
mcollina wants to merge 3 commits into
nodejs:masterfrom
mcollina:stream-next-tick-readable

Conversation

@mcollina

@mcollinamcollina commented Jan 4, 2018

Copy link
Copy Markdown
Member

Fixes: #3203

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

@mcollinamcollina added the semver-major PRs that contain breaking changes and should be released in the next major version. label Jan 4, 2018
@nodejs-github-botnodejs-github-bot added the stream Issues and PRs related to the stream subsystem. label Jan 4, 2018
@mcollina

Copy link
Copy Markdown
MemberAuthor

@mcollina

Copy link
Copy Markdown
MemberAuthor

This solves a recursive push() -> _read() - > push() cycle when multiple push() happen asynchronously. I'm not 100% sure this is something we want to do at this point, nor if this is the right way to achieve this.

It's tagged as semver-major because I feel it might break some edge cases. We might want to revert this quickly if that is the case.

cc @nodejs/streams @nodejs/tsc

@addaleaxaddaleax left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Seems pretty reasonable to me

The dicer CITGM failures appear to be real (or are pretty new at least), /cc @mscdex

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This sentence seems like it’s missing something?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Isn’t setImmediate() enough here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ditto … using setTimeout() tends to introduce race conditions because they might expire before the current event loop turn is over, but setImmediate() always defers (and doesn’t keep test running longer than they need to)

@mcollina
mcollinaforce-pushed the stream-next-tick-readable branch from 6de1dc6 to 102c2f0CompareJanuary 5, 2018 11:47
@mcollina

Copy link
Copy Markdown
MemberAuthor

Fixed nits.
The dicer regression is legit, I'll dig into it.

@mcollina

mcollina commented Jan 5, 2018

Copy link
Copy Markdown
MemberAuthor

@benjamingr

Copy link
Copy Markdown
Member

Benchmarks?

@addaleax

Copy link
Copy Markdown
Member

Benchmarks?

Benchmarks: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/87/

}

if (data.length === 0) {
console.log('pushing null');

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

would prefer to omit the console.log :-)

});

readable.on('end', common.mustCall(() => {
assert.strictEqual(i, (Math.floor(MAX / BATCH) + 1) * BATCH);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please add a comment that explains the calculation

@jasnell

Copy link
Copy Markdown
Member

Still looks good to me. Couple of nits.

@mcollina

Copy link
Copy Markdown
MemberAuthor
 improvement confidence p.value

streams/readable-bigread.js n=1000 0.40 % 0.7330756
streams/readable-bigunevenread.js n=1000 -0.31 % 0.7630930
streams/readable-boundaryread.js type="buffer" n=2000 -1.21 % 0.2752480
streams/readable-boundaryread.js type="string" n=2000 -0.85 % 0.4784480
streams/readable-readall.js n=5000 -1.52 % 0.1030397
streams/readable-unevenread.js n=1000 0.57 % 0.1487255
streams/transform-creation.js n=1000000 3.56 % 0.1932558
streams/writable-manywrites.js n=2000000 -2.82 % 0.2757697

No perf regression!

@mcollinamcollina mentioned this pull request Jan 9, 2018
@mcollina

Copy link
Copy Markdown
MemberAuthor

Added docs, PTAL

@jasnell

Copy link
Copy Markdown
Member

docs LGTM

@mcollina

Copy link
Copy Markdown
MemberAuthor

Landed as 1e0f331.

mcollina added a commit that referenced this pull request Jan 10, 2018
Emit 'readable' always in the next tick, resulting in a single
call to _read() per microtick. This removes the need for the
user to implement buffering if they wanted to call this.push()
multiple times in an asynchronous fashion, as this.push() triggers
this._read() call.
PR-URL: #17979Fixes: #3203
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
@mcollinamcollina added the notable-change PRs with changes that should be highlighted in changelogs. label Jan 10, 2018
mcollina pushed a commit that referenced this pull request Jan 29, 2018
Fixes a regression introduced by the once-per-microtick 'readable'
event emission.
See: #17979
PR-URL: #18372
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@mcollina
mcollina deleted the stream-next-tick-readable branch February 7, 2018 08:01
MayaLekova pushed a commit to MayaLekova/node that referenced this pull request May 8, 2018
Fixes a regression introduced by the once-per-microtick 'readable'
event emission.
See: nodejs#17979
PR-URL: nodejs#18372
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@nevercast

Copy link
Copy Markdown

This landed is Node.js v10.1 yes? That is how I should interpret the linked commits?

@mcollina

Copy link
Copy Markdown
MemberAuthor

Yes this is in 10.1

squaremo added a commit to amqp-node/amqplib that referenced this pull request Jul 16, 2018
The behaviour of the `'readable'` event changed, or was tightened up,
in
nodejs/node#17979
such that it is _always_ called on the next tick. This change appears
first in Node.JS v10.0).
Since we rely on `'readable' in the multiplexing, it means that we
have to be more careful about when we wait for the next event loop to
come around in tests.
The tests tend to be much more brittle than live code with respect to
the order things happen, since they attempt to nail down precise
states or orderings (e.g., "the `unpipe` happened exactly between
these writes").
squaremo added a commit to amqp-node/amqplib that referenced this pull request Aug 3, 2018
The behaviour of the `'readable'` event changed, or was tightened up,
in
nodejs/node#17979
such that it is _always_ called on the next tick. This change appears
first in Node.JS v10.0).
Since we rely on `'readable' in the multiplexing, it means that we
have to be more careful about when we wait for the next event loop to
come around in tests.
The tests tend to be much more brittle than live code with respect to
the order things happen, since they attempt to nail down precise
states or orderings (e.g., "the `unpipe` happened exactly between
these writes").
@mcollinamcollina mentioned this pull request Aug 30, 2018
4 tasks
mcollina added a commit to mcollina/node that referenced this pull request Jan 11, 2019
nodejs#17979 introduced a change in the
doc that was not correct about _read always being called asynchronously.
This does not hold true when it is in flowing mode.
See: nodejs#17979Fixes: nodejs#24919
mcollina added a commit that referenced this pull request Jan 15, 2019
#17979 introduced a change in the
doc that was not correct about _read always being called asynchronously.
This does not hold true when it is in flowing mode.
See: #17979Fixes: #24919
PR-URL: #25442
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yuta Hiroto <hello@hiroppy.me>
addaleax pushed a commit that referenced this pull request Jan 15, 2019
#17979 introduced a change in the
doc that was not correct about _read always being called asynchronously.
This does not hold true when it is in flowing mode.
See: #17979Fixes: #24919
PR-URL: #25442
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yuta Hiroto <hello@hiroppy.me>
BridgeAR pushed a commit to BridgeAR/node that referenced this pull request Jan 16, 2019
nodejs#17979 introduced a change in the
doc that was not correct about _read always being called asynchronously.
This does not hold true when it is in flowing mode.
See: nodejs#17979Fixes: nodejs#24919
PR-URL: nodejs#25442
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Yuta Hiroto <hello@hiroppy.me>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

notable-changePRs with changes that should be highlighted in changelogs.semver-majorPRs that contain breaking changes and should be released in the next major version.streamIssues and PRs related to the stream subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@mcollina@benjamingr@addaleax@jasnell@nevercast@nodejs-github-bot