sz_rust_workflow/engine/
task_manager.rs1use std::sync::Arc;
5
6use uuid::Uuid;
7
8use crate::error::WorkflowResult;
9use crate::instance::{PageRequest, PageResult, Task};
10use crate::repository::TaskRepository;
11
12pub struct TaskManager {
14 task_repo: Arc<dyn TaskRepository>,
15}
16
17impl TaskManager {
18 pub fn new(task_repo: Arc<dyn TaskRepository>) -> Self {
19 Self { task_repo }
20 }
21
22 pub async fn create_tasks(
24 &self,
25 instance_id: &str,
26 node_id: &str,
27 candidates: Vec<String>,
28 ) -> WorkflowResult<Vec<Task>> {
29 let mut tasks = Vec::with_capacity(candidates.len());
30 for candidate in candidates {
31 let task = Task::new_pending(
32 Uuid::new_v4().to_string(),
33 instance_id,
34 node_id,
35 vec![candidate],
36 );
37 self.task_repo.create(&task).await?;
38 tasks.push(task);
39 }
40 Ok(tasks)
41 }
42
43 pub async fn invalidate_by_instance(&self, instance_id: &str) -> WorkflowResult<u64> {
45 self.task_repo.invalidate_by_instance(instance_id).await
46 }
47
48 pub async fn list_pending_by_candidate(
50 &self,
51 candidate: &str,
52 page: PageRequest,
53 ) -> WorkflowResult<PageResult<Task>> {
54 self.task_repo
55 .list_pending_by_candidate(candidate, page)
56 .await
57 }
58
59 pub async fn get(&self, task_id: &str) -> WorkflowResult<Option<Task>> {
61 self.task_repo.get(task_id).await
62 }
63
64 pub async fn update(&self, task: &Task) -> WorkflowResult<()> {
66 self.task_repo.update(task).await
67 }
68
69 pub async fn list_by_instance(&self, instance_id: &str) -> WorkflowResult<Vec<Task>> {
71 self.task_repo.list_by_instance(instance_id).await
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use crate::instance::TaskStatus;
79 use crate::repository::InMemoryTaskRepository;
80
81 #[tokio::test]
82 async fn create_tasks() {
83 let repo = Arc::new(InMemoryTaskRepository::default());
84 let mgr = TaskManager::new(repo);
85 let tasks = mgr
86 .create_tasks("i1", "n1", vec!["u1".into(), "u2".into()])
87 .await
88 .unwrap();
89 assert_eq!(tasks.len(), 2);
90 assert_eq!(tasks[0].status, TaskStatus::Pending);
91 assert_ne!(tasks[0].task_id, tasks[1].task_id);
92 }
93
94 #[tokio::test]
95 async fn invalidate() {
96 let repo = Arc::new(InMemoryTaskRepository::default());
97 let mgr = TaskManager::new(repo);
98 mgr.create_tasks("i1", "n1", vec!["u1".into(), "u2".into()])
99 .await
100 .unwrap();
101 let count = mgr.invalidate_by_instance("i1").await.unwrap();
102 assert_eq!(count, 2);
103 }
104
105 #[tokio::test]
106 async fn list_pending() {
107 let repo = Arc::new(InMemoryTaskRepository::default());
108 let mgr = TaskManager::new(repo);
109 mgr.create_tasks("i1", "n1", vec!["u1".into(), "u2".into()])
110 .await
111 .unwrap();
112 let result = mgr
113 .list_pending_by_candidate("u1", PageRequest::default())
114 .await
115 .unwrap();
116 assert_eq!(result.total, 1);
117 }
118}