新增: 工作流审批取消端到端(StateMachine Arc 共享 + 取消 IPC 注册表)
- StateMachine 内部 HashMap→Arc<Mutex<HashMap>>,clone 共享底层 - DagExecutor 加 state_machine() 访问器 - AppState 加 workflow_state_registry(execution_id→StateMachine) - run_workflow 注册执行器状态机 + 完成清理 - cancel_workflow_node IPC 经 execution_id 取共享引用 set_cancelled,直达 HumanNode 轮询 - 前端取消按钮 + cancelHumanApproval store 方法 - 加 clone_shares 单测验证共享语义
This commit is contained in:
@@ -100,8 +100,15 @@ pub async fn run_workflow(
|
||||
let event_bus = state.event_bus.clone();
|
||||
let db = state.db.clone();
|
||||
let exec_id = execution_id.clone();
|
||||
let state_registry = state.workflow_state_registry.clone();
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let mut executor = DagExecutor::new(event_bus.clone(), exec_id.clone());
|
||||
// 注册执行器状态机:StateMachine 内部 Arc<Mutex>,clone 共享底层 HashMap,
|
||||
// cancel_workflow_node IPC 经 execution_id 取此引用 set_cancelled,直达运行中 HumanNode
|
||||
state_registry
|
||||
.lock()
|
||||
.await
|
||||
.insert(exec_id.clone(), executor.state_machine());
|
||||
let result = executor.run(&runtime_dag, config).await;
|
||||
|
||||
let (status, error) = match &result {
|
||||
@@ -121,6 +128,9 @@ pub async fn run_workflow(
|
||||
tracing::error!("更新工作流完成时间失败: {}", e);
|
||||
}
|
||||
|
||||
// 执行结束(成功/失败)清理状态注册表,防内存泄漏
|
||||
state_registry.lock().await.remove(&exec_id);
|
||||
|
||||
// 执行失败时补发 WorkflowFailed(执行器内部只发 NodeFailed)
|
||||
if let Some(error) = error {
|
||||
event_bus
|
||||
@@ -185,3 +195,29 @@ pub async fn approve_human_approval(
|
||||
state.event_bus.send(event).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 取消工作流节点(人工审批取消)
|
||||
///
|
||||
/// 从执行器状态机注册表取出共享引用,调 `set_cancelled` 置目标节点为 Cancelled。
|
||||
/// StateMachine 内部 Arc<Mutex> 共享底层 HashMap,IPC 写入直达运行中阻塞节点(HumanNode)
|
||||
/// 的 select! 轮询分支,其 is_cancelled 检测到后返回 Err "人工审批被取消"。
|
||||
#[tauri::command]
|
||||
pub async fn cancel_workflow_node(
|
||||
state: State<'_, AppState>,
|
||||
execution_id: String,
|
||||
node_id: String,
|
||||
) -> Result<(), String> {
|
||||
// 经 execution_id 取执行器状态机(与 NodeContext.node_status 共享同一 HashMap)
|
||||
let registry = state.workflow_state_registry.lock().await;
|
||||
let sm = match registry.get(&execution_id) {
|
||||
Some(sm) => sm,
|
||||
None => return Err(format!("工作流 {} 不存在或已结束", execution_id)),
|
||||
};
|
||||
sm.set_cancelled(node_id.clone());
|
||||
tracing::info!(
|
||||
"工作流节点取消:execution_id={}, node_id={}",
|
||||
execution_id,
|
||||
node_id
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ pub fn run() {
|
||||
commands::workflow::list_workflow_executions,
|
||||
commands::workflow::get_workflow_execution,
|
||||
commands::workflow::approve_human_approval,
|
||||
commands::workflow::cancel_workflow_node,
|
||||
// AI 聊天
|
||||
commands::ai::ai_chat_send,
|
||||
commands::ai::ai_chat_stop,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! 应用全局状态 — 数据库、Repo、事件总线、节点注册表、AI 会话
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -16,6 +17,7 @@ use df_storage::crud::{
|
||||
use df_storage::db::Database;
|
||||
use df_workflow::eventbus::EventBus;
|
||||
use df_workflow::registry::NodeRegistry;
|
||||
use df_workflow::state::StateMachine;
|
||||
|
||||
use crate::commands::ai::AiSession;
|
||||
|
||||
@@ -172,6 +174,14 @@ pub struct AppState {
|
||||
// ── LLM 并发控制 ──
|
||||
/// LLM 调用并发上限(全局 + 单对话双层 Semaphore,运行时可调)
|
||||
pub llm_concurrency: LlmConcurrency,
|
||||
// ── 工作流执行状态 ──
|
||||
/// 工作流执行 → 节点状态机注册表
|
||||
///
|
||||
/// run_workflow 创建执行器后注册其 state_machine(StateMachine 内部 Arc<Mutex>,
|
||||
/// clone 共享底层 HashMap,与下沉到 NodeContext.node_status 的是同一份);
|
||||
/// cancel_workflow_node IPC 经 execution_id 取出后 set_cancelled,
|
||||
/// 直达运行中 HumanNode 的 is_cancelled 轮询。执行完成(成功/失败)后移除条目。
|
||||
pub workflow_state_registry: Arc<Mutex<HashMap<String, StateMachine>>>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
@@ -195,6 +205,7 @@ impl AppState {
|
||||
knowledge_config: Arc::new(Mutex::new(KnowledgeConfig::default())),
|
||||
settings: SettingsRepo::new(&db),
|
||||
llm_concurrency: LlmConcurrency::new(3, 2),
|
||||
workflow_state_registry: Arc::new(Mutex::new(HashMap::new())),
|
||||
db,
|
||||
event_bus: EventBus::new(),
|
||||
registry: Arc::new(build_registry()),
|
||||
|
||||
Reference in New Issue
Block a user