Saga Interceptor
Interceptor for saga step execution, enabling pre/post-step hooks with veto capability.
Interceptors allow cross-cutting concerns (logging, metrics, authorization, audit logging) to run before and after every saga step and can veto a step before its side effect fires.
Functional Interface
This is a functional interface (SAM — Single Abstract Method), which means you can use lambda expressions to create interceptors:
val auditInterceptor = SagaInterceptor<OrderContext, OrderResult, Unit> { phase ->
when (phase) {
is StepPhase.Before -> {
auditLog.append("About to execute: ${phase.step.stringValue}")
InterceptorOutcome.Continue
}
is StepPhase.After -> {
auditLog.append("Completed: ${phase.step.stringValue}")
InterceptorOutcome.Continue
}
is StepPhase.Compensation -> {
auditLog.append("Compensated: ${phase.step.stringValue}")
InterceptorOutcome.Continue
}
}
}Veto Semantics
Returning InterceptorOutcome.Veto from a Before phase aborts the step and initiates compensation of all prior completed steps. The veto reason is carried in SagaExecutionError.
Ordering
For multiple interceptors A, B, C registered in order:
Beforeis called A → B → CAfteris called C → B → A (LIFO, mirrors compensation semantics)
Parameters
The context type passed to saga steps
The result type produced by saga steps
The state type (use Unit for non-stateful executors)
Functions
Called once per ca.acendas.kstate.saga.journal.EntryPhase.Compensation entry during saga resume replay, in journal seq order.
Called once per ca.acendas.kstate.saga.journal.EntryPhase.Effect entry during saga resume replay, in journal seq order.