restatedev / restatedev/sdk-typescript
alwaysReplay: run()'s AbortSignal can't observe a sibling fiber's interrupt() within one attempt
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 122
- Forks
- 27
- Avg merge
- 9h 17m
- Merged PRs (30d)
- 8
Description
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 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.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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in fiber.ts at the this.wake interrupt-delivery path, then trace the alwaysReplay suspend-gating behavior around pending run() calls. Reproduce the stated sibling-fiber ordering and determine whether the suspend gate should special-case this case or whether the behavior is accepted as inherent to debug mode; done requires that decision and its resulting behavior to be documented or implemented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- distributed-systems
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100