Skip to main content

Module compensation

Module compensation 

Source
Expand description

Undoing committed effects.

Compensation is a durable lifecycle of its own: Committed → Compensating → Compensated, or CompensationFailed when it fails for good and an operator must finish it. Each attempt is recorded before it runs, retried with backoff, and resumed after a crash: by the next call, or by recovery for a registered CompensableEffect.

A compensation must be idempotent: an attempt that crashed or failed ambiguously is simply run again. Forward CompensationContext::idempotency_key to the remote system. It is stable across attempts and distinct from the effect’s own key.

use agent_effects::{CompensationOutcome, EffectFailure, EffectOutcome, Runtime};
use agent_effects_memory::MemoryStore;

let runtime = Runtime::new(MemoryStore::new());
runtime
    .effect("inventory.reserve", "order-7")
    .run(|_| async { Ok::<_, EffectFailure>("reservation-1".to_string()) })
    .await?;

// Later, the order is cancelled.
let outcome = runtime
    .compensation("inventory.reserve", "order-7")
    .reason("order cancelled")
    .run(|ctx, reservation: Option<String>| async move {
        // Release `reservation`, sending ctx.idempotency_key().
        Ok::<_, EffectFailure>(())
    })
    .await?;
assert_eq!(outcome, CompensationOutcome::Compensated);

Structs§

CompensationBuilder
Undoes a closure effect. Created by Runtime::compensation.
CompensationContext
What a compensation attempt knows about the effect it undoes.

Enums§

CompensationOutcome
How a compensation ended, or where it stands.