pub struct Workflow { /* private fields */ }Expand description
Directed acyclic graph (DAG) representing a workflow.
The workflow maintains tasks as nodes in a petgraph DiGraph, with edges representing hard dependencies between tasks. The graph is validated for cycles on every dependency addition.
§Example
let mut workflow = Workflow::new();
workflow.add_task(MockTask::new("a", "Task A"));
workflow.add_task(MockTask::new("b", "Task B").depends_on("a"));
workflow.add_dependency("b", "a")?;
let order = workflow.execution_order()?;Implementations§
Source§impl Workflow
impl Workflow
Sourcepub fn add_task(&mut self, task: Box<dyn WorkflowTask>) -> NodeIndex
pub fn add_task(&mut self, task: Box<dyn WorkflowTask>) -> NodeIndex
Adds a task to the workflow.
The task is added as an isolated node. Dependencies must be added
separately using add_dependency.
§Arguments
task- Boxed trait object implementing WorkflowTask
§Returns
The NodeIndex of the newly added task in the graph.
§Example
let mut workflow = Workflow::new();
let task = Box::new(MockTask::new("task-1", "First Task"));
workflow.add_task(task);Sourcepub fn add_dependency(
&mut self,
from_task: impl Into<TaskId>,
to_task: impl Into<TaskId>,
) -> Result<(), WorkflowError>
pub fn add_dependency( &mut self, from_task: impl Into<TaskId>, to_task: impl Into<TaskId>, ) -> Result<(), WorkflowError>
Adds a dependency edge between two tasks.
Creates a directed edge from from_task to to_task, indicating
that to_task depends on from_task (from_task must execute first).
§Arguments
from_task- Task ID of the prerequisite (executes first)to_task- Task ID of the dependent (executes after)
§Returns
Ok(())if dependency added successfullyErr(WorkflowError::CycleDetected)if edge creates a cycleErr(WorkflowError::TaskNotFound)if either task doesn’t exist
§Example
workflow.add_dependency("task-a", "task-b")?;
// task-a must execute before task-bSourcepub fn execution_order(&self) -> Result<Vec<TaskId>, WorkflowError>
pub fn execution_order(&self) -> Result<Vec<TaskId>, WorkflowError>
Returns tasks in topological execution order.
Uses Kahn’s algorithm (via petgraph) to produce an ordering where all dependencies appear before their dependents.
§Returns
Ok(Vec<TaskId>)- Tasks in execution orderErr(WorkflowError::CycleDetected)- If graph contains a cycleErr(WorkflowError::EmptyWorkflow)- If workflow has no tasks
Sourcepub fn execution_layers(&self) -> Result<Vec<Vec<TaskId>>, WorkflowError>
pub fn execution_layers(&self) -> Result<Vec<Vec<TaskId>>, WorkflowError>
Returns tasks grouped into parallel execution layers.
Tasks in the same layer have no dependencies between them and can execute concurrently. Tasks in layer N only depend on tasks in layers < N.
This uses the longest path distance from any root (task with in-degree = 0) to determine the layer. All tasks at distance 0 are independent roots, tasks at distance 1 depend only on roots, etc.
§Returns
Ok(Vec<Vec<TaskId>>)- Tasks grouped into layers, where each inner vec contains tasks that can execute in parallelErr(WorkflowError::CycleDetected)- If graph contains a cycleErr(WorkflowError::EmptyWorkflow)- If workflow has no tasks
§Example
For a diamond DAG (a -> b, a -> c, b -> d, c -> d), returns:
vec![
vec!["a"], // Layer 0: root task
vec!["b", "c"], // Layer 1: independent tasks
vec!["d"], // Layer 2: depends on b and c
]Sourcepub fn task_count(&self) -> usize
pub fn task_count(&self) -> usize
Returns the number of tasks in the workflow.
Sourcepub fn contains_task(&self, id: &TaskId) -> bool
pub fn contains_task(&self, id: &TaskId) -> bool
Checks if a task ID exists in the workflow.
Sourcepub fn task_dependencies(&self, id: &TaskId) -> Option<Vec<TaskId>>
pub fn task_dependencies(&self, id: &TaskId) -> Option<Vec<TaskId>>
Returns actual dependencies for a task (from graph edges).
Returns the task IDs that this task depends on, based on the actual graph edges rather than task metadata.
Sourcepub fn apply_suggestions(
&mut self,
suggestions: Vec<DependencySuggestion>,
) -> Result<usize, WorkflowError>
pub fn apply_suggestions( &mut self, suggestions: Vec<DependencySuggestion>, ) -> Result<usize, WorkflowError>
Sourcepub fn preview_suggestions(
&self,
suggestions: &[DependencySuggestion],
) -> Vec<String>
pub fn preview_suggestions( &self, suggestions: &[DependencySuggestion], ) -> Vec<String>
Trait Implementations§
Source§impl TryFrom<YamlWorkflow> for Workflow
impl TryFrom<YamlWorkflow> for Workflow
Source§type Error = YamlWorkflowError
type Error = YamlWorkflowError
Auto Trait Implementations§
impl Freeze for Workflow
impl !RefUnwindSafe for Workflow
impl Send for Workflow
impl Sync for Workflow
impl Unpin for Workflow
impl UnsafeUnpin for Workflow
impl !UnwindSafe for Workflow
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