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

potential bug: wrap now autostarting iterators that were previously not autostarted prior to optimisation work #88

Closed
jeswr opened this issue Sep 13, 2022 · 17 comments · Fixed by #91

Comments

@jeswr
Copy link
Collaborator

jeswr commented Sep 13, 2022

Placeholder - will try create a minimal example or debug tommorow :)

@jeswr
Copy link
Collaborator Author

jeswr commented Sep 20, 2022

On buggy case that I encountered today is the following which blocks on the second line

const iter = wrap(wrap([1, 2, 3], { autoStart: true }))
await iter.toArray()

cc @jacoscaz

@RubenVerborgh
Copy link
Owner

Note that I slightly changed toArray behavior in 174d87c: I found a bug where iterators that had already ended would cause a hang. Probably unrelated though.

@jacoscaz
Copy link
Collaborator

Given the conversation around #45, should we address this before that merge or after?

@RubenVerborgh
Copy link
Owner

I think before; this seems like a bug that we still want fixed in the current vminor.

@jacoscaz
Copy link
Collaborator

@jeswr I'm not sure that is related to autoStart, actually. If autoStart is passed as an option to wrap(), regardless of its value, then the source is passed on to the TransformIterator constructor:

AsyncIterator/asynciterator.ts

Lines 2127 to 2128 in 915a857

if (options && ('autoStart' in options || 'optional' in options || 'source' in options || 'maxBufferSize' in options))
return new TransformIterator<T>(source as MaybePromise<AsyncIterator<T>>, options);

However, with the current main the following doesn't work:

const iter = new TransformIterator([1, 2, 3])
const res = await iter.toArray();

Therefore, I think what's wrong here is:

  1. the fact that we're passing an array as-is to TransformIterator
  2. the fact that we're not catching 1) as a mistake even though we're using TypeScript

Which is not to say that the premise of this issue is wrong. The default behavior if no autoStart option is provided might have changed, indeed.

@RubenVerborgh
Copy link
Owner

RubenVerborgh commented Sep 21, 2022

  1. the fact that we're passing an array as-is to TransformIterator

Indeed; that is not supported. I would have expected the type system to catch it, and TransformIterator to throw (because it cannot attach listeners).

@RubenVerborgh
Copy link
Owner

RubenVerborgh commented Sep 21, 2022

Is it this? 25085c4 / #80

@jacoscaz
Copy link
Collaborator

jacoscaz commented Sep 21, 2022

I think the issue is at line 2128 (see above), which is in the body of wrap(). source (which might be an array) is being cast to MaybePromise<AsyncIterator<T>>, thus bypassing type checks in the TransformIterator constructor.

@RubenVerborgh
Copy link
Owner

I think the intention of the original wrap typing was to not accept autoStart options for IterableSource, and thus only for AsyncIterator. So now the question is: do we adhere to the intended typings, or do we update the function such that options are possible also for IterableSource?

In any case, it does not seem like a regression because this would not have worked before the wrap rewrite.

@jacoscaz
Copy link
Collaborator

jacoscaz commented Sep 21, 2022

IMHO and looking very long-term, the autoStart option should disappear (#25) . When working on new features I would try to limit support for it as much as possible while keeping backward compatibility when it comes to minor versions. I would adhere to the intended typings, disallowing autoStart for IterableSources.

@RubenVerborgh
Copy link
Owner

autoStart will absolutely disappear in the next vmajor.

@jeswr Are you okay with restricting the typings, so reverting the solution to #80? (Which begs the question, for which kinds of arguments do we want to allow the autoStart option?)

@jeswr
Copy link
Collaborator Author

jeswr commented Sep 21, 2022

for which kinds of arguments do we want to allow the autoStart option?

In #45 I renamed it to preBuffer (I think @RubenVerborgh s suggestion). It should only be available on iterators that extend the buffered iterator. When true the buffer will be pre-filled before the first .read() call; when false the buffer will remain empty until the first .read() call is made.

@jeswr
Copy link
Collaborator Author

jeswr commented Sep 21, 2022

In the case of wrap I think we should remove the options parameter entirely to be completely honest. By setting maxBuffer or preBuffer users can suddenly introduce buffering even if they are just wrapping synchronous iterators.

I think it is better to force users to use the TransformIterator in the limited cases where they actually want to use it (I imagine there are less than a handful across all of Comunica where we would need to do this); and include a few docs on upgrading.

@RubenVerborgh
Copy link
Owner

remove the options parameter entirely to be completely honest

But we can't for backward compatibility reasons.

It should only be available on iterators that extend the buffered iterator.

…and we probably don't want this kind of inheritance anymore, btw. I think we should do away with BufferedIterator as a base class, and only have it as a decorator where it is needed.

@RubenVerborgh
Copy link
Owner

@jacoscaz Path of least resistance seems to be accepting arrays; see #91.

@jeswr
Copy link
Collaborator Author

jeswr commented Sep 21, 2022

But we can't for backward compatibility reasons.

This suggestion was for the next vmajor

@jacoscaz
Copy link
Collaborator

…and we probably don't want this kind of inheritance anymore, btw. I think we should do away with BufferedIterator as a base class, and only have it as a decorator where it is needed.

Yes, buffering and transforms are orthogonal concerns and addressing them independently of one another might be a good idea.

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

Successfully merging a pull request may close this issue.

3 participants