-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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: certain sequence of Writable#write and Writable#end will not end stream #29758
Comments
As far as I've been able to tell so far the second Also it seems to be related to the fact that it's an empty string. A quick fix would be to simply make empty buffers and strings a noop in Also I'm not 100% convinced this is related to your http issue. But we can get to that. If I give you a patch can you build Node and run your HTTP case to see if it solves it? |
From a quick look it seems that node/test/common/duplexpair.js Lines 16 to 22 in 82f89ec
As a result the write of the empty chunk does not complete (the callback is not called) and this prevents node/test/common/duplexpair.js Lines 31 to 35 in 82f89ec
This is confirmed by the fact that serverSide.on('finish', common.mustCall()); In #29649 it works with node/lib/internal/stream_base_commons.js Lines 196 to 198 in 82f89ec
A possible way to fix the issue is to not push empty chunks diff --git a/test/common/duplexpair.js b/test/common/duplexpair.js
index 0783aeb861..ba46e20f5d 100644
--- a/test/common/duplexpair.js
+++ b/test/common/duplexpair.js
@@ -24,8 +24,13 @@ class DuplexSocket extends Duplex {
_write(chunk, encoding, callback) {
assert.notStrictEqual(this[kOtherSide], null);
assert.strictEqual(this[kOtherSide][kCallback], null);
- this[kOtherSide][kCallback] = callback;
- this[kOtherSide].push(chunk);
+
+ if (chunk.length) {
+ this[kOtherSide][kCallback] = callback;
+ this[kOtherSide].push(chunk);
+ } else {
+ callback();
+ }
}
_final(callback) { This is consistent with |
cc: @nodejs/streams |
For me it feels like it is masking a more fundamental problem. #29762 is my take on it but I'm out on deep water. It looks to me like that we have logic to trigger |
@ronag The HTTP issue is being caused because the callback of @lpinca I'll start using your patch to avoid empty HTTP is writing an empty string to "flush" the stream, is this strictly necessary? Lines 747 to 748 in db706da
|
An empty chunk should be treated like any other chunk and trigger the read logic. Fixes: nodejs#29758
@ronag Seems to solve the issue for me, great work! |
If nothing is buffered then _read will not be called and the callback will not invoked, effectivly deadlocking. Fixes: nodejs#29758
I ran into a problem where certain
Connection: close
HTTP responses were not being closed, when the response is aContent-Length
response (as opposed to a chunked response), see #29609 and #29649 for background.I've been able to isolate this bug to a problem in "stream" and/or the duplex pair implementation (used by the "tls" module and in tests):
Expected:
Actual:
A write call (empty or non-empty) followed by an empty write call causes this; note how removing either of the calls works around the bug.
I'm not sure if/when this was ever introduced, but this test fails in v10.16.3, v12.10.0, and master branch.
The text was updated successfully, but these errors were encountered: