a3s_flow/execution.rs
1//! Execution handle and state types.
2//!
3//! [`ExecutionState`] is the public snapshot of a workflow execution.
4//! [`ExecutionHandle`] is an internal struct held by [`FlowEngine`] to control
5//! a running execution via a signal channel and a cancellation token.
6
7use std::collections::HashMap;
8use std::sync::{Arc, RwLock};
9
10use serde_json::Value;
11use tokio::sync::{watch, RwLock as AsyncRwLock};
12use tokio_util::sync::CancellationToken;
13
14use crate::result::FlowResult;
15use crate::runner::FlowSignal;
16
17/// Snapshot of a workflow execution's current lifecycle state.
18#[derive(Debug, Clone)]
19pub enum ExecutionState {
20 /// Actively executing nodes.
21 Running,
22 /// Paused at a wave boundary; waiting for a resume signal.
23 Paused,
24 /// Finished successfully. Contains the per-node outputs.
25 Completed(FlowResult),
26 /// Aborted due to a node error. Contains the error message.
27 Failed(String),
28 /// Stopped by an external [`FlowEngine::terminate`](crate::engine::FlowEngine::terminate) call.
29 Terminated,
30}
31
32impl ExecutionState {
33 /// Short label used in error messages.
34 pub fn as_str(&self) -> &'static str {
35 match self {
36 Self::Running => "running",
37 Self::Paused => "paused",
38 Self::Completed(_) => "completed",
39 Self::Failed(_) => "failed",
40 Self::Terminated => "terminated",
41 }
42 }
43
44 /// Returns `true` if the execution has reached a terminal state and will
45 /// not change again.
46 pub fn is_terminal(&self) -> bool {
47 matches!(
48 self,
49 Self::Completed(_) | Self::Failed(_) | Self::Terminated
50 )
51 }
52}
53
54/// Internal control handle for a single execution managed by [`FlowEngine`].
55pub(crate) struct ExecutionHandle {
56 /// Shared, mutable execution state. Updated by the runner task (terminal
57 /// states) and by the engine (pause / resume).
58 pub(crate) state: Arc<AsyncRwLock<ExecutionState>>,
59 /// Sends pause / run signals to the runner task.
60 pub(crate) signal_tx: watch::Sender<FlowSignal>,
61 /// Cancellation token — call `.cancel()` to terminate the execution.
62 pub(crate) cancel: CancellationToken,
63 /// Shared mutable context, accessible from both nodes (via ExecContext)
64 /// and the engine (via CRUD methods). Uses std::sync::RwLock so nodes
65 /// can access it in non-async contexts.
66 pub(crate) context: Arc<RwLock<HashMap<String, Value>>>,
67}