Skip to content
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

Avoid PassThrough to avoid buffering in pipeline #32039

Closed
mcollina opened this issue Mar 2, 2020 · 7 comments
Closed

Avoid PassThrough to avoid buffering in pipeline #32039

mcollina opened this issue Mar 2, 2020 · 7 comments
Assignees
Labels
stream Issues and PRs related to the stream subsystem.

Comments

@mcollina
Copy link
Member

mcollina commented Mar 2, 2020

In the new async-terator capable pipeline as implemented in #31223, we support passing in an async generator function.
Reading from

const pt = new PassThrough();
, it seems we are always wrapping it in a stream internally. This adds overhead and another level of buffering.

We should avoid wrapping it in a PassThrough to avoid said buffering and overhead.

@mcollina mcollina added the stream Issues and PRs related to the stream subsystem. label Mar 2, 2020
@mcollina
Copy link
Member Author

mcollina commented Mar 2, 2020

cc @ronag

@ronag
Copy link
Member

ronag commented Mar 2, 2020

This is only when the last argument in pipeline is not a stream, thus we must create a stream since pipeline should always return a stream.

I don't think this is a big issue. If we want to fix it we need to change the return signature of pipeline.

@ronag
Copy link
Member

ronag commented Mar 2, 2020

i.e. it's to make the following valid:

pipeline(src, function*(source) {
 for await (const chunk of source) {
   yield chunk
 }
}, err => { }).pipe(dst);

Notice the .pipe at the end.

@ronag
Copy link
Member

ronag commented Mar 2, 2020

Looking at the docs it is actually not mentioned that pipeline returns a stream, but I believe that is a common assumption. At least in terms of composition (#32020).

@mcollina
Copy link
Member Author

mcollina commented Mar 2, 2020

I think the current code is correct then, maybe we should add some comments to pipeline as it's not exactly clear what that block would do

@ronag ronag self-assigned this Mar 2, 2020
@ronag
Copy link
Member

ronag commented Mar 2, 2020

I think the current code is correct then, maybe we should add some comments to pipeline as it's not exactly clear what that block would do

I'll prepare a PR this week.

@ronag
Copy link
Member

ronag commented Mar 2, 2020

@mcollina: there is however one case I would like to optimize, consider:

const src = Readable.from(asyncGenerator())
pipeline(src, dst, err => {})

In this case I think pipeline should be able to unwrap the original generator, which would however require Readable.from to somehow re-use the generator function in Symbol.asyncIterator/Symbol.iterator instead of creating a new one.

In the future I would like encourage users to implement readable, transform and writable in terms of generators and wrap only for compatibility.

ronag added a commit to nxtedition/node that referenced this issue Mar 2, 2020
@ronag ronag closed this as completed in 960be15 Mar 7, 2020
MylesBorins pushed a commit that referenced this issue Mar 9, 2020
Fixes: #32039

PR-URL: #32042
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants