* Copyright(c) 2024-2026 China Telecom Cloud Technologies Co., Ltd. All rights
* reserved. ctscat is licensed under Mulan PSL v2. You can use this software
* according to the terms and conditions of the Mulan PSL V2. You may obtain a
* copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for
* more details.
*/
use anyhow::Result;
use std::collections::HashMap;
use tracing::info;
use super::engine::WorkflowEngine;
use super::executor::TaskExecutor;
#[derive(Debug, Clone)]
pub struct WorkflowScheduleItem {
pub name: String,
pub workflow_path: String,
pub cron_expression: String,
pub enabled: bool,
}
pub struct WorkflowScheduler {
items: HashMap<String, WorkflowScheduleItem>,
}
impl WorkflowScheduler {
pub fn new() -> Self {
Self {
items: HashMap::new(),
}
}
pub fn add_workflow(&mut self, item: WorkflowScheduleItem) {
self.items.insert(item.name.clone(), item);
}
pub fn list_workflows(&self) -> Vec<&WorkflowScheduleItem> {
self.items.values().collect()
}
pub async fn start(&self) -> Result<()> {
info!("启动工作流调度器");
info!("已注册的工作流: {}", self.items.len());
for (name, item) in &self.items {
if item.enabled {
info!(" ✓ {}: {}", name, item.cron_expression);
} else {
info!(" ✗ {} (已禁用)", name);
}
}
Ok(())
}
pub async fn execute_workflow(&self, workflow_name: &str) -> Result<()> {
let item = self
.items
.get(workflow_name)
.ok_or_else(|| anyhow::anyhow!("工作流 {} 不存在", workflow_name))?;
info!("手动执行工作流: {}", workflow_name);
let mut engine = WorkflowEngine::from_file(&item.workflow_path)?;
let executor = TaskExecutor::new();
engine.execute(&executor).await?;
let summary = engine.summary();
info!("{}", summary);
Ok(())
}
}
impl Default for WorkflowScheduler {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_workflow_scheduler_creation() {
let scheduler = WorkflowScheduler::new();
assert_eq!(scheduler.list_workflows().len(), 0);
}
#[test]
fn test_workflow_scheduler_add_workflow() {
let mut scheduler = WorkflowScheduler::new();
let item = WorkflowScheduleItem {
name: "test_workflow".to_string(),
workflow_path: "/path/to/workflow.yaml".to_string(),
cron_expression: "0 * * * * *".to_string(),
enabled: true,
};
scheduler.add_workflow(item);
assert_eq!(scheduler.list_workflows().len(), 1);
}
}