pub struct SagaExecutor { /* private fields */ }Expand description
Saga forward phase executor
Executes saga steps sequentially during the forward phase. Coordinates with saga store to persist state and handle failures.
Implementations§
Source§impl SagaExecutor
impl SagaExecutor
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a new saga executor without a saga store
This is suitable for testing. For production, use with_store().
Sourcepub fn with_store(store: Arc<PostgresSagaStore>) -> Self
pub fn with_store(store: Arc<PostgresSagaStore>) -> Self
Create a new saga executor with a saga store
This enables persistence of saga state and recovery from failures.
Sourcepub async fn execute_step(
&self,
saga_id: Uuid,
step_number: u32,
mutation_name: &str,
_variables: &Value,
subgraph: &str,
) -> SagaStoreResult<StepExecutionResult>
pub async fn execute_step( &self, saga_id: Uuid, step_number: u32, mutation_name: &str, _variables: &Value, subgraph: &str, ) -> SagaStoreResult<StepExecutionResult>
Execute a single saga step
Executes a single mutation step within a saga, handling:
- Step state validation (Pending → Executing → Completed)
- @requires field pre-fetching from owning subgraphs
- Entity data augmentation with required fields
- Mutation execution via MutationExecutor
- Result capture and persistence
§Arguments
saga_id- ID of saga being executedstep_number- Step number to execute (1-indexed, 1 = first step)mutation_name- GraphQL mutation operation namevariables- Input variables for the mutation (JSON value)subgraph- Target subgraph name (must exist in federation)
§Returns
StepExecutionResult with:
success: true if step executed successfullydata: Result entity data if successfulerror: Error description if failedduration_ms: Execution time for monitoring
§Errors
Returns SagaStoreError if:
- Saga not found in store
- Step already executed (not in Pending state)
- Subgraph unavailable
- Mutation execution fails
- @requires fields cannot be fetched
§Example
ⓘ
let executor = SagaExecutor::new();
let result = executor.execute_step(
saga_id,
1,
"createOrder",
&json!({"customerId": "c123", "total": 100.0}),
"orders-service"
).await?;
if result.success {
println!("Order created with data: {:?}", result.data);
} else {
eprintln!("Step failed: {}", result.error.unwrap());
// Compensation will be triggered by coordinator
}Sourcepub async fn execute_saga(
&self,
saga_id: Uuid,
) -> SagaStoreResult<Vec<StepExecutionResult>>
pub async fn execute_saga( &self, saga_id: Uuid, ) -> SagaStoreResult<Vec<StepExecutionResult>>
Sourcepub async fn get_execution_state(
&self,
saga_id: Uuid,
) -> SagaStoreResult<ExecutionState>
pub async fn get_execution_state( &self, saga_id: Uuid, ) -> SagaStoreResult<ExecutionState>
Trait Implementations§
Auto Trait Implementations§
impl Freeze for SagaExecutor
impl !RefUnwindSafe for SagaExecutor
impl Send for SagaExecutor
impl Sync for SagaExecutor
impl Unpin for SagaExecutor
impl UnsafeUnpin for SagaExecutor
impl !UnwindSafe for SagaExecutor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more