SagaBuilder

class SagaBuilder<C, R>

DSL builder for creating standalone saga executors.

SagaBuilder provides a fluent API for defining saga steps, compensation logic, idempotency markers, and monitors. The builder is mutable during construction but produces an immutable SagaExecutor.

Usage Example

val saga = sagaExecutor<OrderContext, OrderResult> {
step("reserve-inventory") { context ->
inventoryService.reserve(context.items) // Can be a suspend call
}
compensate { reservationId ->
inventoryService.release(reservationId) // Can be a suspend call
}

step("charge-payment") { context ->
paymentService.charge(context.amount) // Can be a suspend call
}
compensate { transactionId ->
paymentService.refund(transactionId) // Can be a suspend call
}
idempotent(true)

monitor { event ->
logger.info("Saga event: $event")
}
}

// Execute within a coroutine
val result = saga.execute(OrderContext(...))

Step Configuration

Steps are configured using a fluent chain:

  1. step(name) { ... } - Define the step's forward action

  2. compensate { ... } - (Optional) Define compensation for the step

  3. idempotent(true) - (Optional) Mark the step as idempotent

Each call to step() finalizes the previous step and starts a new one.

Parameters

C

The type of context passed to saga steps

R

The type of result produced by saga steps

Constructors

Link copied to clipboard
constructor()

Properties

Link copied to clipboard

Starts the first saga step with "first do 'name' with { ... }" syntax.

Link copied to clipboard

Alternative: starts any saga step (not necessarily first).

Link copied to clipboard

Starts monitor configuration with "watching" keyword.

Functions

Link copied to clipboard

Marks the last step as idempotent using simple syntax.

Link copied to clipboard

Marks the last step as non-idempotent.

Link copied to clipboard

Build the saga executor.

Link copied to clipboard
fun compensate(compensation: suspend (R) -> Unit): SagaBuilder<C, R>

Define compensation logic for the current step.

Link copied to clipboard
infix fun <C, R> SagaBuilder<C, R>.compensateWith(compensation: suspend (R) -> Unit): SagaBuilder<C, R>

Adds compensation to the last defined step using simple syntax (suspend function).

Link copied to clipboard
fun idempotent(value: Boolean = true): SagaBuilder<C, R>

Mark the current step as idempotent (safe to retry).

Link copied to clipboard
fun monitor(monitor: SagaMonitor): SagaBuilder<C, R>

Add a monitor to observe saga events.

fun monitor(handler: suspend (SagaEvent) -> Unit): SagaBuilder<C, R>

Add a monitor using a lambda.

Link copied to clipboard
infix fun <C, R> SagaBuilder<C, R>.monitoring(handler: (SagaEvent) -> Unit)

Adds a saga monitor using "monitoring with" syntax.

Link copied to clipboard
infix fun <C, R> SagaBuilder<C, R>.monitorWith(monitor: SagaMonitor)

Adds a saga monitor instance.

Link copied to clipboard
fun retry(policy: RetryPolicy): SagaBuilder<C, R>

Set retry policy for current step.

Link copied to clipboard
fun step(step: TypedValue, timeout: Duration? = null, forward: suspend (C) -> R): SagaBuilder<C, R>

Define a saga step with forward logic and optional timeout.

fun step(name: String, timeout: Duration? = null, forward: suspend (C) -> R): SagaBuilder<C, R>

Define a saga step with string name (convenience overload).

Link copied to clipboard
infix fun <C, R> SagaBuilder<C, R>.step(name: String): StepActionBuilder<C, R>

Alternative syntax: "step 'name' does { ... }"

Link copied to clipboard
fun timeout(duration: Duration): SagaBuilder<C, R>

Set timeout for current step.