#[non_exhaustive]pub struct WorkflowContext {
pub run_id: Uuid,
pub workflow_name: String,
pub started_at: DateTime<Utc>,
pub auth: AuthContext,
/* private fields */
}Expand description
Context available to workflow handlers.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.run_id: UuidWorkflow run ID.
workflow_name: StringWorkflow name.
started_at: DateTime<Utc>When the workflow started.
auth: AuthContextAuthentication context.
Implementations§
Source§impl WorkflowContext
impl WorkflowContext
Sourcepub fn new(
run_id: Uuid,
workflow_name: String,
db_pool: PgPool,
http_client: CircuitBreakerClient,
) -> Self
pub fn new( run_id: Uuid, workflow_name: String, db_pool: PgPool, http_client: CircuitBreakerClient, ) -> Self
Create a new workflow context.
Sourcepub fn with_persist_step_start(self, persist: bool) -> Self
pub fn with_persist_step_start(self, persist: bool) -> Self
Enable DB writes for record_step_start. By default, only
record_step_complete writes to the database (its upsert handles
the missing start row). Enable this for long-running steps where
observing in-progress state is important.
Sourcepub fn resumed(
run_id: Uuid,
workflow_name: String,
started_at: DateTime<Utc>,
db_pool: PgPool,
http_client: CircuitBreakerClient,
) -> Self
pub fn resumed( run_id: Uuid, workflow_name: String, started_at: DateTime<Utc>, db_pool: PgPool, http_client: CircuitBreakerClient, ) -> Self
Create a resumed workflow context.
Sourcepub fn with_kv(self, kv: Arc<dyn KvHandle>) -> Self
pub fn with_kv(self, kv: Arc<dyn KvHandle>) -> Self
Attach a KV store handle. Called by the runtime before handing the context to the handler.
Sourcepub fn with_env_provider(self, provider: Arc<dyn EnvProvider>) -> Self
pub fn with_env_provider(self, provider: Arc<dyn EnvProvider>) -> Self
Set environment provider.
Sourcepub fn with_resumed_from_sleep(self) -> Self
pub fn with_resumed_from_sleep(self) -> Self
Mark that this context resumed from a sleep (timer expired).
Sourcepub fn with_tenant(self, tenant_id: Uuid) -> Self
pub fn with_tenant(self, tenant_id: Uuid) -> Self
Set the tenant ID.
pub fn tenant_id(&self) -> Option<Uuid>
pub fn is_resumed(&self) -> bool
pub fn workflow_time(&self) -> DateTime<Utc>
pub fn db(&self) -> ForgeDb
Sourcepub async fn conn(&self) -> Result<ForgeConn<'static>>
pub async fn conn(&self) -> Result<ForgeConn<'static>>
Acquire a connection compatible with sqlx compile-time checked macros.
pub fn http(&self) -> HttpClient
pub fn raw_http(&self) -> &Client
pub fn set_http_timeout(&mut self, timeout: Option<Duration>)
Sourcepub fn with_auth(self, auth: AuthContext) -> Self
pub fn with_auth(self, auth: AuthContext) -> Self
Set authentication context.
Sourcepub fn with_saved_state(self, state: HashMap<String, Value>) -> Self
pub fn with_saved_state(self, state: HashMap<String, Value>) -> Self
Restore saved state from persisted data (used on resume).
Sourcepub fn save_state(&self, key: &str, value: impl Serialize) -> Result<()>
pub fn save_state(&self, key: &str, value: impl Serialize) -> Result<()>
Save arbitrary state that persists across suspension points.
Sourcepub fn load_state<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>>
pub fn load_state<T: DeserializeOwned>(&self, key: &str) -> Result<Option<T>>
Load previously saved state. Returns None if the key doesn’t exist.
Sourcepub fn take_saved_state(&self) -> HashMap<String, Value>
pub fn take_saved_state(&self) -> HashMap<String, Value>
Get a snapshot of all saved state for persistence.
Sourcepub fn with_step_states(self, states: HashMap<String, StepState>) -> Self
pub fn with_step_states(self, states: HashMap<String, StepState>) -> Self
Restore step states from persisted data.
pub fn get_step_state(&self, name: &str) -> Option<StepState>
pub fn is_step_completed(&self, name: &str) -> bool
Sourcepub fn is_step_started(&self, name: &str) -> bool
pub fn is_step_started(&self, name: &str) -> bool
Check if a step has been started (running, completed, or failed).
Use this to guard steps that should only execute once, even across workflow suspension and resumption.
pub fn get_step_result<T: DeserializeOwned>(&self, name: &str) -> Option<T>
Sourcepub async fn record_step_start(&self, name: &str) -> Result<()>
pub async fn record_step_start(&self, name: &str) -> Result<()>
Record step start and persist to the database before returning.
If the step is already running or beyond (completed/failed), this is a no-op.
name is part of the workflow’s persisted contract. The #[workflow] macro
hashes every step name (along with wait keys, timeout, and type names) into a
signature stored at run creation. If you rename a step, the next deploy produces
a different signature, and any in-flight run that tries to resume will be blocked
with WorkflowStatus::BlockedSignatureMismatch. Treat step names as stable
public identifiers — change them only under a new workflow version.
Persistence errors are propagated. A swallowed error here would let the workflow continue running while its on-disk state diverged from memory, producing a “completed” run with no recorded step rows.
Sourcepub async fn record_step_complete(
&self,
name: &str,
result: Value,
) -> Result<()>
pub async fn record_step_complete( &self, name: &str, result: Value, ) -> Result<()>
Record step completion and persist to the database before returning.
Errors from the persist call are propagated so the workflow can react rather than continuing past a step the database never observed.
Sourcepub async fn record_step_failure(
&self,
name: &str,
error: impl Into<String>,
) -> Result<()>
pub async fn record_step_failure( &self, name: &str, error: impl Into<String>, ) -> Result<()>
Record step failure and persist to the database before returning.
Errors from the persist call are propagated so the workflow doesn’t declare a step “failed” only in memory while the row still claims it is running.
Sourcepub async fn record_step_compensated(&self, name: &str) -> Result<()>
pub async fn record_step_compensated(&self, name: &str) -> Result<()>
Record step compensation and persist to the database before returning.
Persistence is inline (not tokio::spawn’d): if the process crashes
after the in-memory state changes but before the row update lands, a
later resume would see the step as still completed and re-run its
compensation handler. Inline await ties durability to the caller and
surfaces failures through Result.
pub fn completed_steps_reversed(&self) -> Vec<String>
pub fn all_step_states(&self) -> HashMap<String, StepState>
pub fn elapsed(&self) -> Duration
Sourcepub fn register_compensation(
&self,
step_name: &str,
handler: CompensationHandler,
)
pub fn register_compensation( &self, step_name: &str, handler: CompensationHandler, )
Register a compensation handler for a step.
Limitation: compensation handlers are in-memory closures and cannot
survive a process restart. If the process crashes between step completion
and workflow termination, compensation handlers for completed steps are
lost. The WorkflowExecutor::cancel method detects this and fails the
workflow with a clear message indicating manual remediation is required.
This is an inherent constraint of closure-based compensation; a durable
alternative would require serializable compensation descriptors (e.g.,
naming a registered handler + captured args as JSON).
pub fn get_compensation_handler( &self, step_name: &str, ) -> Option<CompensationHandler>
pub fn has_compensation(&self, step_name: &str) -> bool
Sourcepub async fn run_compensation(&self) -> Vec<(String, bool)>
pub async fn run_compensation(&self) -> Vec<(String, bool)>
Run compensation for all completed steps in reverse order. Returns a list of (step_name, success) tuples.
pub fn compensation_handlers(&self) -> HashMap<String, CompensationHandler>
Sourcepub async fn wait_for_event<T: DeserializeOwned>(
&self,
event_name: &str,
timeout: Option<Duration>,
) -> Result<T>
pub async fn wait_for_event<T: DeserializeOwned>( &self, event_name: &str, timeout: Option<Duration>, ) -> Result<T>
Wait for an external event with optional timeout.
The workflow suspends until the event arrives or the timeout expires. Events are correlated by the workflow run ID.
§Example
let payment: PaymentConfirmation = ctx.wait_for_event(
"payment_confirmed",
Some(Duration::from_secs(7 * 24 * 60 * 60)), // 7 days
).await?;Sourcepub fn take_suspend_reason(&self) -> Option<SuspendReason>
pub fn take_suspend_reason(&self) -> Option<SuspendReason>
Take the stored suspension reason, if any.
Called by the executor after the handler returns an error to determine whether the error represents a suspension or a real failure.
Trait Implementations§
Source§impl EnvAccess for WorkflowContext
impl EnvAccess for WorkflowContext
fn env_provider(&self) -> &dyn EnvProvider
fn env(&self, key: &str) -> Option<String>
fn env_or(&self, key: &str, default: &str) -> String
fn env_require(&self, key: &str) -> Result<String>
fn env_parse<T: FromStr>(&self, key: &str) -> Result<T>
Source§fn env_parse_or<T: FromStr>(&self, key: &str, default: T) -> Result<T>
fn env_parse_or<T: FromStr>(&self, key: &str, default: T) -> Result<T>
fn env_contains(&self, key: &str) -> bool
Auto Trait Implementations§
impl Freeze for WorkflowContext
impl !RefUnwindSafe for WorkflowContext
impl Send for WorkflowContext
impl Sync for WorkflowContext
impl Unpin for WorkflowContext
impl UnsafeUnpin for WorkflowContext
impl !UnwindSafe for WorkflowContext
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
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more