sh_layer2/workflow_engine/
mod.rs1mod dag;
6mod executor;
7mod node;
8
9pub use dag::Dag;
10pub use executor::WorkflowExecutor;
11pub use node::{Node, NodeStatus};
12
13use async_trait::async_trait;
14use serde::{Deserialize, Serialize};
15
16use crate::types::{Layer2Result, TaskId};
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct WorkflowInput {
21 pub task: String,
22 pub context: serde_json::Value,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct WorkflowOutput {
28 pub task_id: TaskId,
29 pub results: Vec<NodeResult>,
30 pub status: WorkflowStatus,
31 pub duration_ms: u64,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct NodeResult {
37 pub node_id: String,
38 pub status: NodeStatus,
39 pub output: Option<serde_json::Value>,
40 pub error: Option<String>,
41 pub duration_ms: u64,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
46pub enum WorkflowStatus {
47 Pending,
48 Running,
49 Completed,
50 Failed,
51 Cancelled,
52}
53
54#[async_trait]
56pub trait WorkflowEngineTrait: Send + Sync {
57 fn add_node(&mut self, node: Node) -> Layer2Result<()>;
59
60 fn add_edge(&mut self, from: &str, to: &str) -> Layer2Result<()>;
62
63 async fn execute(&self, input: WorkflowInput) -> Layer2Result<WorkflowOutput>;
65
66 async fn cancel(&self, task_id: &TaskId) -> Layer2Result<bool>;
68
69 fn status(&self, task_id: &TaskId) -> Layer2Result<WorkflowStatus>;
71
72 fn validate(&self) -> Layer2Result<Vec<String>>;
74
75 fn node_count(&self) -> usize;
77
78 fn edge_count(&self) -> usize;
80}
81
82#[async_trait]
84pub trait NodeExecutor: Send + Sync {
85 async fn execute(&self, node: &Node, input: &WorkflowInput) -> Layer2Result<serde_json::Value>;
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_workflow_input_creation() {
95 let input = WorkflowInput {
96 task: "test".to_string(),
97 context: serde_json::Value::Null,
98 };
99 assert_eq!(input.task, "test");
100 }
101}