-
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
stream: fix backpressure when multiple sync push #19613
Conversation
cc @nodejs/streams @mafintosh @addaleax |
lib/_stream_readable.js
Outdated
@@ -310,7 +310,7 @@ function chunkInvalid(state, chunk) { | |||
// 'readable' event will be triggered. | |||
function needMoreData(state) { | |||
return !state.ended && | |||
(state.needReadable || | |||
(// state.needReadable || |
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.
This should be removed completely.
lib/_stream_readable.js
Outdated
@@ -536,7 +536,18 @@ function emitReadable_(stream) { | |||
if (!state.destroyed && (state.length || state.ended)) { | |||
stream.emit('readable'); | |||
} | |||
state.needReadable = !state.flowing && !state.ended; | |||
|
|||
// the stream need another readable event if |
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.
s/need/needs/
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 please capitalize all sentences.
lib/_stream_readable.js
Outdated
// the stream need another readable event if | ||
// 1. it is not flowing, as the flow mechanism will take | ||
// care of it. | ||
// 2. it is not neded. |
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.
s/neded/needed/
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 think it's meant to be "ended"
lib/_stream_readable.js
Outdated
// care of it. | ||
// 2. it is not neded. | ||
// 3. we are below the highWaterMark, because it is | ||
// waiting some .read() call to bring it under the |
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.
s/some/for some/
CITGM (master): https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/1343/ |
43be365
to
69e5f3a
Compare
lib/_stream_readable.js
Outdated
// The stream needs another readable event if | ||
// 1. It is not flowing, as the flow mechanism will take | ||
// care of it. | ||
// 2. It is not eneded. |
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.
s/eneded/ended/
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 keep doing typos, thanks!
69e5f3a
to
225a693
Compare
There have been a graceful-fs and spdy failures on citgm on the previous run, but they seem unrelated (just flaky). Running citgm again. CITGM: https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/1344/ |
|
||
const ws = stream.Writable({ | ||
write: common.mustCall(function(data, enc, cb) { | ||
setTimeout(cb, 1); |
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.
nit: setImmediate()
?
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.
done.
const length = this._readableState.length; | ||
|
||
console.log(length, total); | ||
assert(length < 4 * total); |
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.
Would it make sense to tune this even tighter, and check that length <= HWM
? As I understand it that should be the relevant condition for making sure that _read()
doesn’t get called
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.
This is not going to be possible, as we are over highWaterMark here in half of the cases even on Node 8. I'll make the check stricter with length <= total
, because that's what will happen.
@@ -310,8 +310,7 @@ function chunkInvalid(state, chunk) { | |||
// 'readable' event will be triggered. |
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.
Hm … what about this comment? It sounds like it needs to be adjusted, since it explains why we wanted needReadable
here in the first place?
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 think that comment is actually wrong. It says
if it's past the high water mark, we can push in some more.
However it has a check (simplified) as:
return state.length < state.highWaterMark
I would prefer that we tackle that in another PR, as I would like to get this landed as it solves a potential memory leak situation. If you are ok I'll open an issue about it, as it needs to be investigated and explained better.
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.
@addaleax is this approach good for you? This should be ready to land.
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.
@mcollina Sure, deferring to another PR sounds fine to me. :)
225a693
to
c4cb320
Compare
c4cb320
to
77f4d29
Compare
Great to get this fixed! Thanks everyone. |
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.
LGTM with the caveat that I, like most people, don’t have a good overview of the internal streams state machine
@@ -310,8 +310,7 @@ function chunkInvalid(state, chunk) { | |||
// 'readable' event will be triggered. |
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.
@mcollina Sure, deferring to another PR sounds fine to me. :)
Landed as d37e59f. |
PR-URL: #19613 Fixes: #19601 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
Closes: #19601
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes