Skip to content

Saga pattern helper — distributed transactions with compensations #88

Description

@pathosDev

Distributed-transaction-style workflows ("book flight, charge card, email confirmation, on failure roll back") map naturally to actors but writing the orchestration by hand is repetitive. Saga is the standard pattern: a list of steps, each with an explicit compensation action that runs on failure.

API sketch:

```ts
const result = await Saga.run([
{
do: async () => bookingActor.tell({ kind: 'reserve', flightId }),
compensate: async () => bookingActor.tell({ kind: 'release', flightId }),
},
{
do: async () => paymentActor.tell({ kind: 'charge', amount }),
compensate: async () => paymentActor.tell({ kind: 'refund', amount }),
},
{
do: async () => emailActor.tell({ kind: 'send', template: 'confirmation' }),
// no compensation — emails can't be unsent, but step 3 is the last one anyway
},
]);
```

Scope:

  • `Saga.run(steps, opts?)`: runs steps in order; on failure, runs `compensate` of all completed steps in reverse.
  • `opts.persistenceId?` enables crash-safe sagas — write each step's status to a journal so a restart resumes from where it stopped.
  • Built on top of `PersistentActor` when persistenceId is set; pure in-memory otherwise.

Out of scope:

  • Cross-process saga coordination (saga lives in one actor; the steps it triggers can be cluster-wide).
  • Long-running (> hours) sagas with state that lives in DD — separate issue if needed.

Estimate: 4-5 days.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: lowNice-to-have / niche / demand-driven

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions