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

Stream: Error trying to paginate data using Readable.take operator #44026

Open
ErickWendel opened this issue Jul 28, 2022 · 7 comments
Open

Stream: Error trying to paginate data using Readable.take operator #44026

ErickWendel opened this issue Jul 28, 2022 · 7 comments
Labels
stream Issues and PRs related to the stream subsystem.

Comments

@ErickWendel
Copy link
Member

ErickWendel commented Jul 28, 2022

Version

18.4

Platform

Darwin

Subsystem

No response

What steps will reproduce the bug?

I was trying to paginate results from a Stream using the .take operator but it's throwing an AbortError

import {  Readable } from 'node:stream'
const data = Readable.from(['a', 'b', 'c', 'd'])
data.take(1).forEach(x => console.log(x));
data.take(2).forEach(x => console.log(x));
// AbortError: The operation was aborted

or

import {  Readable } from 'node:stream'
const data = Readable.from(['a', 'b', 'c'])
data.take(1).pipe(process.stdout)
data.take(2).pipe(process.stdout)
// AbortError: The operation was aborted

However, using the code below keeps the stream working and prints the array without one char

import {  Readable } from 'node:stream'
const data = Readable.from(['a', 'b', 'c', 'd'])
data.take(2).forEach(x => console.log(x, 'take 2'));
data.drop(1).take(1).forEach(x => console.log(x, 'drop 1 + take 1'));

/*
a take 2
d take 2
c drop 1 + take 1
*/

or

import {  Readable } from 'node:stream'
const data = Readable.from(['a', 'b', 'c'])
data.take(1).pipe(process.stdout)
data.drop(1).take(2).pipe(process.stdout)
//ac

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

Consume chunks as specified

const data = Readable.from(['a', 'b', 'c'])
data.take(1).pipe(process.stdout)
data.take(2).pipe(process.stdout)
// abc

What do you see instead?

// AbortError: The operation was aborted

Additional information

@benjamingr

@ErickWendel ErickWendel changed the title Error trying to paginate data using Readable.take Stream: Error trying to paginate data using Readable.take Jul 28, 2022
@ErickWendel ErickWendel changed the title Stream: Error trying to paginate data using Readable.take Stream: Error trying to paginate data using Readable.take operator Jul 28, 2022
@MoLow MoLow added the stream Issues and PRs related to the stream subsystem. label Jul 28, 2022
@ErickWendel
Copy link
Member Author

cc @nodejs/streams

@mcollina
Copy link
Member

This seems expected as any of those operators consume the stream. Maybe we should just document them better?

@ErickWendel
Copy link
Member Author

ErickWendel commented Aug 23, 2022

it seems confusing to the userland. Shouldn't these operators try consuming the stream the same way? Or in this case, change the .take function to not abort the operation as when it goes with .drop.

When I read take it reminds me of the pagination methods such as skip and limit. If the goal is just to pick a specific range of bytes I'd suggest renaming it to pick instead. (or keep only the stream.read(byteLength)

What do you think?

@mcollina
Copy link
Member

This looks confusing, I possibly overlooked the detail that the following works:

import {  Readable } from 'node:stream'
const data = Readable.from(['a', 'b', 'c', 'd'])
data.take(2).forEach(x => console.log(x, 'take 2'));
data.drop(1).take(1).forEach(x => console.log(x, 'drop 1 + take 1'));

/*
a take 2
d take 2
c drop 1 + take 1
*/

Which I didn't expect to.

@benjamingr @ronag wdyt?

@ErickWendel
Copy link
Member Author

Should I try fixing it? @nodejs/streams

@mcollina
Copy link
Member

Yes! I would like to see what the fix look like.

@rluvaton
Copy link
Member

This also happening on regular compose and toArray

const { Readable, compose} = require('node:stream');

compose(
   Readable.from(['a', 'b', 'c', 'd']),
   async function*(stream) {
      for await (const chunk of stream) {
         yield chunk;
         return;
      }
   }
).forEach(x => console.log(x))

This will print out 'a' and then fail on AbortError

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

No branches or pull requests

4 participants