-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
http2: fix condition where data is lost #18895
Conversation
lib/internal/http2/core.js
Outdated
stream.push(null); | ||
stream[kMaybeDestroy](null, code); | ||
|
||
// defer this until we actuallhy emit end |
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.
typo
lib/internal/http2/core.js
Outdated
stream.push(null); | ||
stream[kMaybeDestroy](); | ||
|
||
// defer this until we actuallhy emit end |
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.
ditto
661f3ff
to
cd0f03c
Compare
lib/internal/http2/core.js
Outdated
stream.on('end', stream[kMaybeDestroy]); | ||
stream.push(null); | ||
|
||
// TODO mcollina: are we sure this is correct? |
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.
The comment style we generally use for these is // TODO(mcollina): …
lib/internal/http2/core.js
Outdated
// TODO mcollina: are we sure this is correct? | ||
if (stream.readableLength === 0) { | ||
// autoresume, the stream needs to finish | ||
stream.resume() |
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.
What net.Socket
s do is calling .read(0)
unconditionally after .push(null)
. Could you try to see if that makes sense? I would really like to merge these bits of code and it would be great if we could avoid these discrepancies…
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 would be nice to combine the two tests as they are so similar, most parts could be reused.
lib/internal/http2/core.js
Outdated
this.closed) { | ||
this.destroy(); | ||
// this should return, but eslint complains | ||
// return |
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.
The last return
is just considered obsolete. I am not sure if the comment really adds a benefit.
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.
the comment states that, if any more code is added in there, a return should be included.
This makes it explicit. Can you recommend some alternative wording that are ok for you?
(I'm generally 👎 on that eslint rule)
lib/internal/http2/core.js
Outdated
stream.push(null); | ||
stream[kMaybeDestroy](null, code); | ||
|
||
// defer this until we actually emit end |
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 you be so kind and upper case the first character of each comment and punctuate the comments? :-)
stream[kMaybeDestroy](); | ||
} else { | ||
stream.on('end', stream[kMaybeDestroy]); | ||
stream.push(null); |
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 the stream.push
necessary 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 it is. It's needed to close the stream.
!this.closed)) { | ||
return; | ||
} | ||
if (error || code !== NGHTTP2_NO_ERROR) { |
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 would move the code !== NGHTTP2...
check to the next if. That way it is clearer that destroy is not called with error in that case. Or do I miss something 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.
The code is correct as it is. There can be an error
(from net or tls) or the stream can return an error code - but that's not mapped to a JS ERROR
yet.
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.
What I meant is if code !== NGHTTP2_NO_ERROR
, error
will be falsy. And in that case error
does not have to be passed to this.destroy
. This is the case in the next if
statement and therefore I would move the code !== NGHTTP2...
case down.
But it is not important.
Could this maybe also have some influence on some of our test failures? |
@BridgeAR yes, this could be the cause of some of our spurious failures. |
cd0f03c
to
b23cd58
Compare
@addaleax PTAL Can you also check if that TODO that I left is correct? I'm starting to think it is. |
lib/internal/http2/core.js
Outdated
return; | ||
} | ||
|
||
// TODO mcollina: remove usage of _*State properties |
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 TODO
is still in the previous style ;)
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.
b23cd58
to
eb76f83
Compare
The two tests checks two different things, one for the compat API and one for the stream. I would keep them separate as it might be more maintainable in the long run. We have a really poor isolation logic between various sub-tests. |
eb76f83
to
c3dcc3c
Compare
Landed in dbe645f |
PR-URL: #18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: nodejs#18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: nodejs#18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Backport-PR-URL: #20456 PR-URL: #18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
PR-URL: nodejs#18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Backport-PR-URL: #20456 PR-URL: #18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Backport-PR-URL: #20456 PR-URL: #18895 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
Fix a condition that would make a Http2Stream lose some data if pipe is used with a very short stream.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
http2