Skip to content

PersistentFSM stateTimeout — time-based transitions #65

@pathosDev

Description

@pathosDev

`PersistentFSM` (#52) ships with command-driven transitions only. The original issue noted time-based transitions (`stateTimeout` à la Akka) as out-of-scope for v1; this issue tracks the follow-up.

Use case: payment-processing flow times out after 5 minutes if no `captured` event arrives — auto-transition to `'expired'` state with a synthetic event.

API sketch:

```ts
transitions = {
pending: {
pay: { event: { kind: 'paid' }, next: 'paid' },
},
paid: {
capture: { event: { kind: 'captured' }, next: 'captured' },
// NEW — fire after 5 min in this state if no command transitions us out
_timeout: {
afterMs: 5 * 60_000,
event: { kind: 'expired' },
next: 'expired',
},
},
};
```

Implementation notes:

  • The base class arms a per-actor timer in `onRecoveryComplete` and after every successful transition.
  • Timer fires → synthesizes an internal command, dispatches via the same persist-then-apply pipeline so recovery sees a real event.
  • Needs to NOT fire on a transition that landed via recovery (timer must be relative to the `_state-entered timestamp`, persisted alongside state).

Out of scope: transition guards based on wall clock (next sub-issue if needed).

Estimate: 2 days.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions