StatefulSagaExecutor

interface StatefulSagaExecutor<C, R, S>

Executes stateful saga steps with forward and compensating logic.

StatefulSagaExecutor orchestrates the execution of saga steps that share typed state, enabling "smart compensation" where compensation logic can make decisions based on the execution progress of later steps.

Execution Model

  1. Execute steps sequentially in order with shared state access

  2. If a step fails, compensate completed steps in reverse order (LIFO)

  3. Compensation receives both step result and current saga state

  4. Notify monitors of all lifecycle events

  5. Return structured result with final state

State Isolation

Each execution creates an isolated copy of the initial state. Multiple concurrent executions do not share state. The final state is included in the result for observability and debugging.

Usage Example

data class PaymentState(val escrowCaptured: Boolean = false)

val saga = sagaExecutor<Cart, Order>(PaymentState()) {
first `do` "take-payment" with { cart ->
updateState { it.copy(amount = payment.amount) }
createOrder(cart)
} and undo {
if (state.escrowCaptured) refund() else returnEscrow()
}
}

when (val result = saga.execute(cart)) {
is StatefulSagaResult.Completed -> {
println("Order: ${result.value}, Final state: ${result.finalState}")
}
is StatefulSagaResult.Aborted -> {
println("Failed: ${result.error}, State at failure: ${result.finalState}")
}
}

Parameters

C

The type of context passed to saga steps

R

The type of result produced by saga steps

S

The type of shared saga state

Functions

Link copied to clipboard
abstract fun addMonitor(monitor: SagaMonitor)

Add a monitor to observe saga events.

Link copied to clipboard
abstract suspend fun execute(context: C): StatefulSagaResult<R, S>

Execute the saga with the given context.

abstract suspend fun execute(context: C, coroutineContext: CoroutineContext = EmptyCoroutineContext, timeout: Duration? = null): StatefulSagaResult<R, S>

Execute the saga with the given context, coroutine context, and optional timeout.

Link copied to clipboard
abstract fun removeMonitor(monitor: SagaMonitor)

Remove a monitor.