新增: 工作流审批取消端到端(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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user