-
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
"readable" event behaving inconsistently #18058
Comments
I can confirm I am seeing the same behaviour. Which one is wrong - the docs, or the implementation ? |
I think what you are experiencing with both handlers is a doc problem. The docs reports:
Flowing mode happens when you are adding a
Would you like to send a PR with a doc update? |
hey @mcollina , thank you for your reply and sorry that I disappeared for 20 days 😆 I would gladly submit a PR clarifying the behaviour with both handlers! Hopefully it will be much quicker. However what I still didn't get is that why |
I think I might be onto something. If I implement my own simple stream: const stream = require("stream");
var xx = stream.Duplex();
var things = [];
xx._read = function(){
return xx.push(things.pop() || null );
}
xx._write = function(d){
return things.push(d);
};
xx.on('readable', () => {
var d = xx.read();
console.log("readable", d && d.length);
});
xx.on('end', () => {
console.log('end');
});
xx.write("lol", "utf8"); and run this I will get proper output:
However if I remove What I have found is that http response overrides both Since Fine, the comment says that most of the job will be done by I have a hunch that I'm onto something, but I can't quite prove or refute. But it seems I decoupled my Do you think you might have some ideas how to finish the case? :) |
I've been pretty puzzled by this bug. #18939 removes those, and the tests are not failing. Can you check if that solves your problem? |
#18994 fixes it, unfortunately it's a semver-major change. |
In Streams3 the 'readable' event/.read() method had a lower precedence than the `'data'` event that made them impossible to use them together. This make `.resume()` a no-op if there is a listener for the `'readable'` event, making the stream non-flowing if there is a `'data'` listener. Fixes: nodejs#18058
From nodejs docs (https://nodejs.org/api/stream.html#stream_event_readable):
I decided to try this increased throughput. However, I ran into an issue of compatibility of
'readable'
with'data'
, as well as inconsistent behaviour of'readable'
on its own, in the case of http responses.Issue
From https://nodejs.org/api/stream.html#stream_event_readable:
However, it seems that if
'readable'
is used in conjunction with'data'
, then it emits false-positive end-of-stream events (i.e. where thestream.read()
isnull
), along with no useful data (all useful data was consumed by'data'
handler).If it's used on its own, without
'data'
handler, it fails to detect the end-of-stream event in case when the stream is not delayed and short (i.e. when it's consumed in one go).How to reproduce
Code
Here is a simple node snippet that creates a simple http server with a simple handler for 3 urls for different cases and then sends different requests in chain. In order not to introduce other unrelated errors (like
ParseError
onTCP.onread
orBad Request
responses), all content lengths were carefully provided for each request/response. The code is lengthy but simple (with hooks for envvars for easy changes).The http server serves 3 types of responses: immediate short, immediate appended and delayed appended.
How to run
For both
'data'
and'readable'
events:$ cat test.js | docker run -i node:9.3.0
For only
'data'
event:$ cat test.js | docker run -e NO_READABLE=true -i node:9.3.0
For only
'readable'
event:$ cat test.js | docker run -e NO_DATA=true -i node:9.3.0
Outputs
Case 1 (both handlers)
Notice the first
readable null
inSending /delay
that tells us the stream is finished yet it's not.Case 2 (just '
data'
event)No problems with
'data'
, as expected.Case 3 (only
'readable'
event)Notice the absence of any
readable
lines withnull
inSending /
andSending /more
.The text was updated successfully, but these errors were encountered: