修复: 工作流审批闭环(execution_id 下沉 + 共享状态机 + HumanNode 真审批)
- B-06: DagExecutor 接收 execution_id 下沉到 NodeContext,消除 dummy-execution-id 硬编码 - B-07: NodeContext.node_status 共享 self.state_machine.clone()(is_cancelled 可工作) - B-03a: HumanNode execute 重写为 subscribe→send→select! 循环(响应/超时/取消 + execution_id+node_id 双键 + Lagged 容忍),删假返回"同意" - eventbus.rs 删 try_recv_human_approval 死代码 - 新增 human_node 7 单测(正常/双键过滤/超时/非法决策/自由文本) 照 B-03-人工审批响应机制.md 设计。cargo check 0 error,df-nodes 14 + df-workflow 11 test 全过
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
use tokio::sync::broadcast;
|
||||
use tokio::sync::broadcast::error::SendError;
|
||||
use df_core::events::{WorkflowEvent, HumanApprovalResponse};
|
||||
use df_core::events::WorkflowEvent;
|
||||
|
||||
/// 事件总线
|
||||
#[derive(Debug)]
|
||||
@@ -44,13 +44,6 @@ impl EventBus {
|
||||
pub fn emit_human_approval_request(&self, event: WorkflowEvent) -> Result<usize, SendError<WorkflowEvent>> {
|
||||
self.sender.send(event)
|
||||
}
|
||||
|
||||
/// 尝试获取人工审批响应(简化版本,实际需要实现状态存储)
|
||||
pub fn try_recv_human_approval(&self, _execution_id: &str, _node_id: &str) -> Option<HumanApprovalResponse> {
|
||||
// TODO: 实现审批响应的存储和检索
|
||||
// 目前返回 None,需要配合前端实现
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for EventBus {
|
||||
|
||||
@@ -16,14 +16,20 @@ pub struct DagExecutor {
|
||||
event_bus: EventBus,
|
||||
/// 节点状态机
|
||||
state_machine: StateMachine,
|
||||
/// 工作流执行 ID(由调用方传入,下沉到每个 NodeContext)
|
||||
execution_id: String,
|
||||
}
|
||||
|
||||
impl DagExecutor {
|
||||
/// 创建执行器
|
||||
pub fn new(event_bus: EventBus) -> Self {
|
||||
///
|
||||
/// `execution_id` 为本次工作流执行的唯一标识,会下沉到每个节点的 NodeContext,
|
||||
/// 用于节点内的事件关联、审计追踪等。
|
||||
pub fn new(event_bus: EventBus, execution_id: String) -> Self {
|
||||
Self {
|
||||
event_bus,
|
||||
state_machine: StateMachine::new(),
|
||||
execution_id,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,9 +79,10 @@ impl DagExecutor {
|
||||
node_id: node_id.clone(),
|
||||
inputs,
|
||||
config: initial_config.clone(),
|
||||
execution_id: "dummy-execution-id".to_string(), // TODO: 应该从 workflow_execution 获取
|
||||
execution_id: self.execution_id.clone(),
|
||||
event_bus: self.event_bus.clone(),
|
||||
node_status: StateMachine::new(),
|
||||
// 共享执行器状态机,使节点(如 HumanNode)能读取真实状态而非空状态机
|
||||
node_status: self.state_machine.clone(),
|
||||
};
|
||||
|
||||
// 仅捕获节点共享引用与所有权上下文,避免与 self 借用冲突
|
||||
@@ -196,7 +203,7 @@ mod tests {
|
||||
dag.add_node("a".to_string(), Box::new(SleepNode { sleep_ms: 100 }));
|
||||
dag.add_node("b".to_string(), Box::new(SleepNode { sleep_ms: 100 }));
|
||||
|
||||
let mut executor = DagExecutor::new(EventBus::new());
|
||||
let mut executor = DagExecutor::new(EventBus::new(), "test-exec".to_string());
|
||||
let start = std::time::Instant::now();
|
||||
let outputs = executor.run(&dag, serde_json::Value::Null).await.unwrap();
|
||||
let elapsed = start.elapsed();
|
||||
@@ -219,7 +226,7 @@ mod tests {
|
||||
dag.add_node("c".to_string(), Box::new(SleepNode { sleep_ms: 10 }));
|
||||
dag.add_edge("a".to_string(), "c".to_string());
|
||||
|
||||
let mut executor = DagExecutor::new(EventBus::new());
|
||||
let mut executor = DagExecutor::new(EventBus::new(), "test-exec".to_string());
|
||||
let err = executor
|
||||
.run(&dag, serde_json::Value::Null)
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user