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.
Under
alwaysReplay, a fiber parked inops.run()cannot observe aninterrupt()call issued from a sibling fiber that itself needs a durable resume (e.g.sleep) to reach that call, within the same attempt:run()is still pending.run()can only stop being pending viainterrupt()(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.wakeinfiber.ts) is unaffected and 100% reliable — the worker'scatchblock and result are correct in every mode. Only the auxiliaryrun()-scopedAbortSignalfiring promptly enough to cancel a real external side effect (e.g. an in-flightfetch) is affected, specifically underalwaysReplaywith 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.