sagas

command
v1.1.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

README

Saga (Process Manager) Example

Coordinate a long-running, multi-step business process with automatic compensation on failure.

A saga (process manager) reacts to events and issues the next commands, driving a workflow that spans multiple aggregates. This example implements an OrderFulfillmentSaga that orchestrates payment → inventory → shipment, tracks its state across steps, and — when a step fails — emits compensating commands to undo the work already done.

What this demonstrates

  • Event-driven orchestrationOrderFulfillmentSaga.HandleEvent receives each mink.StoredEvent and returns the []mink.Commands to run next (e.g. OrderPlacedProcessPaymentCommand).
  • Explicit state machine — the saga advances through SagaState values (Started, PaymentPending, InventoryPending, ShipmentPending, Completed, Cancelled, Compensating) as events arrive.
  • Happy pathOrderPlacedPaymentProcessedInventoryReservedShipmentCreated walks the saga to Completed, generating one command per step.
  • Compensation — when InventoryReservationFailed arrives after payment, the saga moves to Compensating and emits RefundPaymentCommand + CancelOrderCommand to roll back.
  • Completion checkIsComplete reports whether the saga reached a terminal state (Completed or Cancelled).
  • Event persistence — the same events are appended to and reloaded from an in-memory EventStore.

Running

go run ./examples/sagas

No infrastructure required — uses the in-memory adapter.

What happens

  1. An in-memory EventStore and a fresh OrderFulfillmentSaga are created.
  2. Happy path — four events (OrderPlaced, PaymentProcessed, InventoryReserved, ShipmentCreated) are fed one at a time to saga.HandleEvent. Each prints a progress line (📦 Order placed…, 💳 Payment received…, 📦 Inventory reserved…, ✅ Shipment created…) and returns the next command.
  3. The saga state is printed: order ID, final State (Completed), the PaymentProcessed/InventoryReserved/ShipmentCreated flags, and IsComplete (true).
  4. The generated commands are listed: ProcessPayment, ReserveInventory, CreateShipment, CompleteOrder.
  5. Failure path — a second saga processes OrderPlaced, PaymentProcessed, then InventoryReservationFailed. It prints ⚠️ compensating…, sets State to Compensating, and returns the compensation commands.
  6. The failed saga's state is printed, followed by its compensation commands: RefundPayment and CancelOrder.
  7. Event store — the happy-path events are appended to stream saga-order-001 with store.Append, then reloaded with store.Load; the count of stored events is printed and the demo exits.

Key APIs

  • mink.New(adapter) — create the EventStore over the memory adapter.
  • mink.StoredEvent — the stored event value passed into the saga's HandleEvent.
  • mink.Command — interface for commands returned by the saga; each defines CommandType().
  • mink.CommandBase — embedded base for the concrete commands (ProcessPaymentCommand, ReserveInventoryCommand, CreateShipmentCommand, CompleteOrderCommand, CancelOrderCommand, RefundPaymentCommand).
  • store.Append — persist events to a stream (with mink.ExpectVersion(mink.NoStream)).
  • store.Load — read events back from a stream.

Note: this example runs the saga logic directly to keep the workflow readable — it collects the commands each step returns rather than dispatching them through a command bus. See full-ecommerce for a saga wired into an end-to-end pipeline.

Documentation

Overview

Example: Saga (Process Manager) Pattern

This example demonstrates how to use the saga testing utilities to build and test long-running business processes.

Run with: go run .

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL