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

Clean up yield inheritance #115

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

shaseley
Copy link
Collaborator

@shaseley shaseley commented Mar 5, 2025

  1. Key the scheduling state based on the {{Scheduler}} to prevent leaking it across (potentially cross-origin) windows. This changes the event loop's continuation state to be a small wrapper around a map. The continuation state is propagated in the same way, but the scheduler state is unique to the scheduler and not shared. In practice there will only be one entry in this map (a task or microtask can only have originated from one task), but the mechanism is generic enough to support other use cases, implementations can optimize this, and the key/value mapping hopefully makes the isolation clear.

    Alternatively, we could propagate only the state for the current scheduler, but we don't always know the current scheduler, e.g. in "queue a microtask", and this model is different enough from AsyncContext and Chrome's "Task Attribution" that we'd need a separate mechanism, which is a performance concern. The main behavioral difference is how propagating is handled in the case of A --> (B microtask) --> A. With this approach, the context is preserved in the second call to A, which matches the synchronous behavior of A --> calls B --> calls A.

  2. Propagate the current scheduling state in "queue a microtask", unless coming from JavaScript, in which case the propagation is handled by the abstract job closure. Previously, the state would be inherited only if it wasn't reset by another microtask or after the postTask callback ran. This fixes the inconsistency, making directly scheduled microtasks match microtasks originating from JavaScript.


Preview | Diff

 1. Key the scheduling state based on the {{Scheduler}} to prevent
    leaking it across (potentially cross-origin) windows. This changes
    the event loop's continuation state to be a small wrapper around a
    map. The continuation state is propagated in the same way, but the
    scheduler state is unique to the scheduler and not shared. In
    practice there will only be one entry in this map (a task or
    microtask can only have originated from one task), but the mechanism
    is generic enough to support other use cases, implementations
    can optimize this, and the key/value mapping hopefully makes the
    isolation clear.

    Alternatively, we could propagate only the state for the current
    scheduler, but we don't always know the current scheduler, e.g. in
    "queue a microtask", and this model is different enough from
    AsyncContext and Chrome's "Task Attribution" that we'd need a
    separate mechanism, which is a performance concern. The main
    behavioral difference is how propagating is handled in the case of
    A --> (B microtask) --> A. With this approach, the context is
    preserved in the second call to A, which matches the synchronous
    behavior of A --> calls B --> calls A.

 2. Propagate the current scheduling state in "queue a microtask",
    unless coming from JavaScript, in which case the propagation is
    handled by the abstract job closure. Previously, the state would be
    inherited only if it wasn't reset by another microtask or after the
    postTask callback ran. This fixes the inconsistency, making directly
    scheduled microtasks match microtasks originating from JavaScript.
@shaseley shaseley force-pushed the yield-inheritance-fix branch from 7680be8 to c887dc3 Compare March 5, 2025 23:05
@shaseley shaseley marked this pull request as ready for review March 5, 2025 23:36
@shaseley shaseley linked an issue Mar 5, 2025 that may be closed by this pull request
@shaseley
Copy link
Collaborator Author

shaseley commented Mar 5, 2025

Hi @smaug---- would you mind taking a look? I'm going to start migrating stuff to HTML, which will make the monkey patching easier to reason about, but I wanted to have a starting point. The indirection is maybe a little overkill, but I think having the map makes the isolation clear, and it can probably be expanded later to support AsyncContext since the microtask propagation should be the same, but TBD.

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 this pull request may close these issues.

Clarify that the scheduling state is supposed to be per event loop
1 participant