-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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 premature destroy #21051
http2: fix premature destroy #21051
Conversation
Check stream._writableState.finished instead of stream.writable as the latter can lead to premature calls to destroy and dropped writes on busy processes.
/cc @nodejs/http2 @bzoz Could you check if this fixes the failures you were seeing on Windows? If not, please let me know what the new debugging output is as it would likely be a different / new bug. Thanks in advance!! |
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 if CI is good
(Maybe also /cc @ryzokuken)
Umm, this should fix the bug, but it uses the hidden property? @apapirovski I understand that literally everyone in the userland uses /cc @mcollina |
Landed in 7b6c428 |
Sorry, this does not fix the issue: Path: parallel/test-http2-pipe
(node:2416) ExperimentalWarning: The http2 module is an experimental API.
events.js:167
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onread (net.js:656:25)
Emitted 'error' event at:
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
Command: C:\Users\Administrator\Desktop\node\Release\node.exe C:\Users\Administrator\Desktop\node\test\parallel\test-http2-pipe.js I'll try to produce the |
@bzoz thanks. I'm guessing there's another race condition elsewhere in the code. This would've fixed the last one I saw based on the debug logs. |
Got it: === release test-http2-pipe ===
Path: parallel/test-http2-pipe
(node:1060) ExperimentalWarning: The http2 module is an experimental API.
Http2Session server (19) session created
Http2Session server (19) i/o stream consumed
Http2Session server (19) scheduling write
Http2Session client (24) session created
Http2Session client (24) i/o stream consumed
Http2Session client (24) scheduling write
Http2Priority: parent: 0, weight: 16, exclusive: 0
Http2Session client (24) request submitted
Http2Session client (24) submitting request
Http2Session client (24) request submitted, new stream id 1
HttpStream 1 (27) [Http2Session client (24)] queuing 1 buffers to send
HttpStream 1 (27) [Http2Session client (24)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 9 bytes to send
Http2Session server (19) wants read? 1
Http2Session client (24) sending pending data
Http2Session client (24) nghttp2 has 24 bytes to send
Http2Session client (24) nghttp2 has 9 bytes to send
Http2Session client (24) nghttp2 has 25 bytes to send
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16384 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16384 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16384 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16384 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16384 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16384 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16383 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16383 bytes to send directly
Http2Session client (24) wants read? 1
Http2Session client (24) receiving 9 bytes
Http2Session client (24) receiving 9 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 4
Http2Session client (24) settings refreshed for session
Http2Session client (24) sending pending data
Http2Session client (24) nghttp2 has 9 bytes to send
Http2Session client (24) wants read? 1
Http2Session client (24) wants read? 1
Http2Session server (19) receiving 23360 bytes
Http2Session server (19) receiving 23360 bytes [wants data? 1]
Http2Session server (19) complete frame received: type: 4
Http2Session server (19) settings refreshed for session
Http2Session server (19) beginning headers for stream 1
Http2Session server (19) complete frame received: type: 1
Http2Session server (19) handle headers frame for stream 1
HttpStream 1 (29) [Http2Session server (19)] submitting response
HttpStream 1 (29) [Http2Session server (19)] response submitted
HttpStream 1 (29) [Http2Session server (19)] reading starting
HttpStream 1 (29) [Http2Session server (19)] writable side shutdown
Http2Session server (19) buffering data chunk for stream 1, size: 16384, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading stopped
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 6900, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 9 bytes to send
Http2Session server (19) nghttp2 has 34 bytes to send
Http2Session server (19) reading outbound data for stream 1
Http2Session server (19) no more data for stream 1
Http2Session server (19) nghttp2 has 9 bytes to send
Http2Session server (19) wants read? 1
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 52 bytes
Http2Session client (24) receiving 52 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 4
Http2Session client (24) settings refreshed for session
Http2Session client (24) beginning headers for stream 1
HttpStream 1 (27) [Http2Session client (24)] starting headers, category: 1
Http2Session client (24) complete frame received: type: 1
Http2Session client (24) handle headers frame for stream 1
Http2Session client (24) complete frame received: type: 0
Http2Session client (24) handling data frame for stream 1
Http2Session client (24) sending pending data
Http2Session client (24) wants read? 1
Http2Session server (19) receiving 23360 bytes
Http2Session server (19) receiving 23360 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 9484, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading stopped
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 13867, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 13 bytes
Http2Session client (24) receiving 13 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 8
Http2Session client (24) sending pending data
Http2Session client (24) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 2517, flags: 0
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 4774, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7300, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 4318 bytes
Http2Session server (19) receiving 4318 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 4309, flags: 0
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) complete frame received: type: 4
Http2Session server (19) settings refreshed for session
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 13 bytes
Http2Session client (24) receiving 13 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 8
Http2Session client (24) sending pending data
Http2Session client (24) wants read? 1
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) scheduling write
HttpStream 1 (29) [Http2Session server (19)] reading stopped
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 13 bytes
Http2Session client (24) receiving 13 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 8
Http2Session client (24) sending pending data
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 1 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 1 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) deferring stream 1
HttpStream 1 (27) [Http2Session client (24)] queuing 1 buffers to send
Http2Session client (24) wants read? 1
Http2Session client (24) wants read? 1
Http2Session client (24) scheduling write
Http2Session client (24) sending pending data
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16384 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16384 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16384 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16384 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16384 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16384 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16382 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16382 bytes to send directly
Http2Session client (24) wants read? 1
Http2Session server (19) receiving 7310 bytes
Http2Session server (19) receiving 7310 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 1, flags: 0
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 7291, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7300, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 1793, flags: 0
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 5498, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7300, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 3586, flags: 0
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 3705, flags: 0
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session server (19) wants read? 1
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) scheduling write
HttpStream 1 (29) [Http2Session server (19)] reading stopped
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 13 bytes
Http2Session client (24) receiving 13 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 8
Http2Session client (24) sending pending data
Http2Session client (24) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7300, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 13 bytes
Http2Session client (24) receiving 13 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 8
Http2Session client (24) sending pending data
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 2 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 2 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) deferring stream 1
HttpStream 1 (27) [Http2Session client (24)] queuing 1 buffers to send
Http2Session client (24) wants read? 1
Http2Session client (24) wants read? 1
Http2Session client (24) scheduling write
Http2Session client (24) sending pending data
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) stream 1 has pending outbound data
Http2Session client (24) sending 16312 bytes for data frame on stream 1
Http2Session client (24) nghttp2 has 16312 bytes to send directly
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) deferring stream 1
Http2Session client (24) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 5379, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 1912, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7300, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) wants read? 1
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7170, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 2, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) complete frame received: type: 0
Http2Session server (19) handling data frame for stream 1
Http2Session server (19) buffering data chunk for stream 1, size: 110, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session server (19) wants read? 1
Http2Session client (24) receiving 13 bytes
Http2Session client (24) receiving 13 bytes [wants data? 1]
Http2Session client (24) complete frame received: type: 8
Http2Session client (24) sending pending data
Http2Session client (24) wants read? 1
Http2Session client (24) write finished with status 0
HttpStream 1 (27) [Http2Session client (24)] writable side shutdown
Http2Session client (24) scheduling write
Http2Session client (24) sending pending data
Http2Session client (24) reading outbound data for stream 1
Http2Session client (24) no more data for stream 1
Http2Session client (24) stream 1 closed with code: 0
HttpStream 1 (27) [Http2Session client (24)] closed with code 0
HttpStream 1 (27) [Http2Session client (24)] destroying stream
HttpStream 1 (27) [Http2Session client (24)] destroying stream
Http2Session client (24) nghttp2 has 9 bytes to send
Http2Session client (24) wants read? 1
Http2Session client (24) submitting goaway
Http2Session client (24) scheduling write
Http2Session client (24) destroying session
Http2Session client (24) closing session
Http2Session client (24) terminating session with code 0
Http2Session client (24) sending pending data
Http2Session client (24) nghttp2 has 17 bytes to send
Http2Session client (24) nghttp2 has 17 bytes to send
Http2Session client (24) wants read? 0
HttpStream 1 (27) [Http2Session client (24)] tearing down stream
Http2Session client (24) write finished with status -4081
Http2Session server (19) receiving 7300 bytes
Http2Session server (19) receiving 7300 bytes [wants data? 1]
Http2Session server (19) buffering data chunk for stream 1, size: 7300, flags: 0
HttpStream 1 (29) [Http2Session server (19)] reading starting
Http2Session server (19) sending pending data
Http2Session server (19) nghttp2 has 13 bytes to send
Http2Session server (19) wants read? 1
Http2Session server (19) wants read? 1
Http2Session server (19) receiving -4077 bytes
HttpStream 1 (29) [Http2Session server (19)] sending rst_stream with code 2
Http2Session server (19) sending pending data
HttpStream 1 (29) [Http2Session server (19)] destroying stream
HttpStream 1 (29) [Http2Session server (19)] destroying stream
Http2Session server (19) destroying session
Http2Session server (19) closing session
events.js:167
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at TCP.onread (net.js:656:25)
Emitted 'error' event at:
at emitErrorNT (internal/streams/destroy.js:82:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:50:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
Command: C:\Users\Administrator\Desktop\node\Release\node.exe C:\Users\Administrator\Desktop\node\test\parallel\test-http2-pipe.js |
Check stream._writableState.finished instead of stream.writable as the latter can lead to premature calls to destroy and dropped writes on busy processes. PR-URL: nodejs#21051 Fixes: nodejs#20750 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Check stream._writableState.finished instead of stream.writable as the latter can lead to premature calls to destroy and dropped writes on busy processes. PR-URL: nodejs#21051 Fixes: nodejs#20750 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Check stream._writableState.finished instead of stream.writable as the latter can lead to premature calls to destroy and dropped writes on busy processes. PR-URL: nodejs#21051 Fixes: nodejs#20750 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Check stream._writableState.finished instead of stream.writable as the latter can lead to premature calls to destroy and dropped writes on busy processes. Backport-PR-URL: #22850 PR-URL: #21051 Fixes: #20750 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
Check
stream._writableState.finished
instead ofstream.writable
as the latter can lead to premature calls to destroy and dropped writes on busy processes.Fixes: #20750
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes