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

asyncPeekerate fails with "It is no longer the active part" when used on asyncBatch #493

Open
alex-kowalczyk opened this issue Mar 27, 2023 · 2 comments

Comments

@alex-kowalczyk
Copy link

The following code, intending to get a page of results with information is it the last page, fails with
Cannot take from this split part. It is no longer the active part.

const asyncIterator = await asyncPeekerate(asyncBatch(pageSize, await generatorFn()));
const {value} = await asyncIterator.asIterator().next();
const page = await arrayFromAsync(value);
const done = asyncIterator.done

Expected results

I should receive first page and information is it the last one or not

Actual results

 Error: Cannot take from this split part. It is no longer the active part.
        at AsyncPartIterator.assertActive (/src/node_modules/iter-tools/internal/async-parts-iterator.js:49:15)
        at AsyncPartIterator._callee$ (/src/node_modules/iter-tools/internal/async-parts-iterator.js:63:22)
        at tryCatch (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:44:17)
        at Generator.<anonymous> (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:125:22)
        at Generator.next (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:69:21)
        at asyncGeneratorStep (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
        at _next (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:9)
        at /src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:27:7
        at new Promise (<anonymous>)
        at AsyncPartIterator.<anonymous> (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:19:12)
        at AsyncPartIterator.next (/src/node_modules/iter-tools/internal/async-parts-iterator.js:96:22)
        at _callee$ (/src/node_modules/iter-tools/impls/$to-array/async-to-array.js:30:30)
        at tryCatch (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:44:17)
        at Generator.<anonymous> (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:125:22)
        at Generator.next (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/regeneratorRuntime.js:69:21)
        at asyncGeneratorStep (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
        at _next (/src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:9)
        at /src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:27:7
        at new Promise (<anonymous>)
        at /src/node_modules/iter-tools/node_modules/@babel/runtime/helpers/asyncToGenerator.js:19:12
        at __asyncToArray (/src/node_modules/iter-tools/impls/$to-array/async-to-array.js:11:24)
        at asyncToArray (/src/node_modules/iter-tools/impls/$to-array/async-to-array.js:108:10)
@conartist6
Copy link
Member

Your example code should look like this:

const peekr = await asyncPeekerate(asyncBatch(pageSize, generatorFn()));
const page = await arrayFromAsync(peekr.value);

The fixes are:

  • generatorFn() does not need to be awaited even if it is an async generator.
  • peekr already loads the first item for you, so you definitely don't need to do peekr.asIterator().next(). I've confirmed that this is what is causing the bug you're seeing, but I don't yet understand why. As far as I can tell the code you wrote should not error, although I would expect it to silently discard the first page.

@conartist6
Copy link
Member

Oh ok, yeah, I get what was happening. peekerate always has one value buffered so that you can look at peekr.done and peekr.value.

The interesting part is the implementation ofpeekr.asIterator().next:

async next() {
const { peekr } = this;
const { current } = peekr;
await peekr.advance();
return current;
}

What's happening is that you're getting the first split part but then immediately requesting the second part, which is causing the first part to be marked as inactive.

Likely this does represent a bug in the library as the more correct thing to do would be to mark a previous split part as inactive only when the user attempts to read from a later split part, not just when a new one is created as is happening here:

this.currentPart.inactive = true;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants