Skip to content

alwaysReplay: run()'s AbortSignal can't observe a sibling fiber's interrupt() within one attempt #773

Description

@nstandif

Under alwaysReplay, a fiber parked in ops.run() cannot observe an interrupt() call issued from a sibling fiber that itself needs a durable resume (e.g. sleep) to reach that call, within the same attempt:

  • Delivering the sibling's already-ready durable completion requires the attempt to suspend.
  • The SDK won't suspend while any run() is still pending.
  • The pending run() can only stop being pending via interrupt() (gated behind that same suspend) or its own fallback/rejection.

Closed loop — the run() closure only ever settles via whatever resolves it locally, never via the cross-fiber abort, in that attempt. Once settled, the journal entry is fixed; replays don't re-invoke the closure, they replay the recorded result.

Reproduction:

   httpRequest.on("close", () => {
-    abortController.abort();
+    if (!httpRequest.readableEnded) abortController.abort();
   });

Applying this correct fix (needed independently, see #745) exposes the gap — before it, a spurious abort on every normal half-close happened to overwrite the test's side-channel observation, masking this.

Scope: the fiber-throw interrupt-delivery path (this.wake in fiber.ts) is unaffected and 100% reliable — the worker's catch block and result are correct in every mode. Only the auxiliary run()-scoped AbortSignal firing promptly enough to cancel a real external side effect (e.g. an in-flight fetch) is affected, specifically under alwaysReplay with this exact cross-fiber ordering shape.

Not fixed here — deferred pending a decision on whether alwaysReplay's suspend-gating should special-case this, or whether it's accepted as inherent to the debug mode.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions