pub struct WorkflowGuardState { /* private fields */ }Expand description
Mutable runtime state tracked by the guard during a workflow execution.
Shared between parent and child workflows via Arc<Mutex<_>> so that
limits are enforced globally across the entire run tree.
§Examples
use ironflow_engine::guard::{WorkflowGuardConfig, WorkflowGuardState};
let mut state = WorkflowGuardState::new();
let config = WorkflowGuardConfig::new().with_max_depth(2);
state.record_invocation("workflow-a");
state.record_invocation("workflow-b");
assert!(state.check(&config, "workflow-c").is_err());Implementations§
Source§impl WorkflowGuardState
impl WorkflowGuardState
Sourcepub fn new() -> Self
pub fn new() -> Self
Create a fresh guard state for a new workflow execution.
§Examples
use ironflow_engine::guard::WorkflowGuardState;
let state = WorkflowGuardState::new();
assert_eq!(state.depth(), 0);
assert_eq!(state.total_invocations(), 0);Sourcepub fn total_invocations(&self) -> u32
pub fn total_invocations(&self) -> u32
Total workflow invocations so far.
Sourcepub fn total_tokens_used(&self) -> u64
pub fn total_tokens_used(&self) -> u64
Total tokens consumed so far.
Sourcepub fn call_chain(&self) -> &[String]
pub fn call_chain(&self) -> &[String]
The current call chain (workflow name stack).
Sourcepub fn elapsed_secs(&self) -> u64
pub fn elapsed_secs(&self) -> u64
Seconds elapsed since the workflow started.
Sourcepub fn check(
&self,
config: &WorkflowGuardConfig,
target_workflow: &str,
) -> Result<(), WorkflowRejection>
pub fn check( &self, config: &WorkflowGuardConfig, target_workflow: &str, ) -> Result<(), WorkflowRejection>
Read-only check: would invoking target_workflow violate any limit?
Does not mutate state. Call this before
record_invocation.
§Errors
Returns the specific WorkflowRejection variant that would be
violated.
§Examples
use ironflow_engine::guard::{WorkflowGuardConfig, WorkflowGuardState, WorkflowRejection};
let state = WorkflowGuardState::new();
let config = WorkflowGuardConfig::new().with_max_depth(0);
let err = state.check(&config, "child").unwrap_err();
assert!(matches!(err, WorkflowRejection::MaxDepthExceeded { .. }));Sourcepub fn record_invocation(&mut self, target_workflow: &str)
pub fn record_invocation(&mut self, target_workflow: &str)
Record that a sub-workflow invocation is starting.
Increments depth and fan-out counter, and pushes the workflow name onto the call chain for cycle detection.
§Examples
use ironflow_engine::guard::WorkflowGuardState;
let mut state = WorkflowGuardState::new();
state.record_invocation("child-workflow");
assert_eq!(state.depth(), 1);
assert_eq!(state.total_invocations(), 1);
assert_eq!(state.call_chain(), &["child-workflow"]);Sourcepub fn record_return(&mut self)
pub fn record_return(&mut self)
Record that a sub-workflow invocation has returned.
Decrements depth and pops the last entry from the call chain. Safe to call even on failure paths (the guard must never leak depth).
§Examples
use ironflow_engine::guard::WorkflowGuardState;
let mut state = WorkflowGuardState::new();
state.record_invocation("child");
assert_eq!(state.depth(), 1);
state.record_return();
assert_eq!(state.depth(), 0);
assert!(state.call_chain().is_empty());Sourcepub fn record_tokens(
&mut self,
config: &WorkflowGuardConfig,
tokens_used: u64,
) -> Result<u64, WorkflowRejection>
pub fn record_tokens( &mut self, config: &WorkflowGuardConfig, tokens_used: u64, ) -> Result<u64, WorkflowRejection>
Record tokens consumed by an agent step.
Returns the remaining token budget, or an error if the budget is now exhausted.
§Errors
Returns WorkflowRejection::TokenBudgetExhausted when the
cumulative usage exceeds the configured maximum.
§Examples
use ironflow_engine::guard::{WorkflowGuardConfig, WorkflowGuardState, WorkflowRejection};
let mut state = WorkflowGuardState::new();
let config = WorkflowGuardConfig::new().with_max_workflow_tokens(100);
assert!(state.record_tokens(&config, 50).is_ok());
assert!(state.record_tokens(&config, 60).is_err());