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

Detached generators don’t resume when reattached #144

Closed
mbostock opened this issue Nov 10, 2023 · 1 comment · Fixed by #290
Closed

Detached generators don’t resume when reattached #144

mbostock opened this issue Nov 10, 2023 · 1 comment · Fixed by #290
Assignees
Labels
bug Something isn’t working

Comments

@mbostock
Copy link
Member

For example, given this generator:

const j = (async function* () {
  for (let j = 0; true; ++j) {
    yield j;
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }
})();

If you reference the value of j like so:

The value of j is: ${j}.

Then everything works as expected. But, if you delete the reference to j, save, and then restore the reference to j, then j will resolve to undefined instead of incrementing once per second. I would guess that this has something to do with the generator being consumed lazily, and something bad is happening if there is no longer a downstream observer. 🤔

@mbostock mbostock added the bug Something isn’t working label Nov 10, 2023
@mbostock mbostock added this to the General availability milestone Nov 13, 2023
@mbostock
Copy link
Member Author

I spent a bit of time looking at this. It’s tricky. Some observations…

When a generator variable is invalidated, the generator is returned (terminated) here:

https://github.com/observablehq/runtime/blob/037fd2de7f1b461025d2cac91acd05639adce722/src/runtime.js#L269

When a variable becomes no longer reachable, the variable is invalidated here:

https://github.com/observablehq/runtime/blob/037fd2de7f1b461025d2cac91acd05639adce722/src/runtime.js#L108

The combination of this means that the generator is terminated when the associated variable is no longer reachable. But the problem is resumption: recomputing the variable j doesn’t create a new generator; it simply returns the existing one that was returned by cell 42. And since that generator has already been returned, the subsequent call to generator.next returns {done: true, value: undefined}.

I think probably this means that variables that are no longer reachable should not be invalidated — they’re still valid, just not reachable. But that means that a variable that becomes reachable doesn’t necessarily need to be computed. And it means that we don’t want to keep pulling from the generator while it’s not reachable; we should wait until it becomes reachable again. 🤔

@mbostock mbostock self-assigned this Nov 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn’t working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant