Skip to content

Avoid PassThrough to avoid buffering in pipeline #32039

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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>
# for free to join this conversation on GitHub. Already have an account? # 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