| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Beforehand the async iterator for readline was created lazily when the stream was accessed which meant no events were buffered. In addition stream handling was modernized and improved in the process to support backpressure correctly. A test was added to assert this. Fixes: nodejs#28565 Fixes: nodejs#33463
| const onIterator = on(this, 'line'); | ||
| this.once('close', () => onIterator.return()); | ||
| const readable = Readable.from(onIterator).map((line) => line[0]); | ||
| this[kLineObjectStream] = readable; |
There was a problem hiding this comment.
Note the current implementation does not close the readline.Interface when the async iterable is closed. This can be easily fixed if we want by doing readable.once('close', () => this.close()) though I am not sure which behavior is better.
Sorry, something went wrong.
There was a problem hiding this comment.
I think it should close it. The pattern for async iterators is that the stream is fully consumed after the loop. Maybe add an option?
Sorry, something went wrong.
There was a problem hiding this comment.
I think it should close it too but was hesitant to change the existing behavior. If you agree it should be closed I'll close it.
Sorry, something went wrong.
There was a problem hiding this comment.
I think so.
Sorry, something went wrong.
There was a problem hiding this comment.
lgtm
Sorry, something went wrong.
|
(Note to self: This also needs a doc update to remove the sentence about not attaching the listener early enough) |
Sorry, something went wrong.
|
The failing for backpressure test looks kind of wrong I think? It wraps the events with a readable settings its highWaterMark to 16 (default for objectMode) and stops asking for data once we buffered 16 items by calling pause. This means that other consumers of the readline.Interface won't get line events they're listening to which is kind of confusing behavior I think? I think for the very least we should check no one else is listening to line before pausing. this is like one consumer in a multicast system pausing the broadcast for everyone because it can't buffer enough. Alternatively I'm not sure backpressure makes a ton of sense here? I'll consider |
Sorry, something went wrong.
I'm probably lost, could you link?
If you are using an async iterator you are the primary consumer of that data. This should probably documented somewhere but a lot of unwanted things happen when multiple consumers are attached. |
Sorry, something went wrong.
There is a test that checks that we .pause the readline.Interface after the readable associated with the async iterator reaches its watermark (which is a non-configurable 16 lines since that's the default for objectMode). You can see the test in https://github.com/nodejs/node/blob/master/test/parallel/test-readline-async-iterators-backpressure.js It's kind of confusing since if errors happen those will be buffered too in the async iterable which is why this behavior changed in from: #29428 . This isn't too hard to "fix" since from already sets reading = false when the readable has buffered enough - it just defaults to a highWaterMark of 1 and not 16. |
Sorry, something went wrong.
|
I think I'll split this PR into two - one just fixing the bug and another to discuss backpressure to make the discussion easier - hope that's ok? |
Sorry, something went wrong.
|
go for it |
Sorry, something went wrong.
Sorry, something went wrong.
Sorry, something went wrong.
|
I want to wait for #41276 to land first |
Sorry, something went wrong.
|
|
||
| await setImmediate(); | ||
| const result = []; | ||
| for await (const item of rl) { |
There was a problem hiding this comment.
It seems like it's redundant await, isn't it?
Sorry, something went wrong.
|
This needs a rebase/ |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Beforehand the async iterator for readline was created lazily when the
stream was accessed which meant no events were buffered. In addition
stream handling was modernized and improved in the process to support
backpressure correctly. A test was added to assert this.
There is a cost here (the stream is always created) I believe it is well worth it to enable modern usage of readline without dropping lines.
There is also an unrelated bugfix here (we return the wrong thing from events.on(...).throw(...).
cc @nodejs/readline @nodejs/streams @jfriend00
Fixes: #28565
Fixes: #33463