Skip to main content

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