场景4:长计算的暂停与恢复
设计一个简单的,由三个节点组成的流程:Draft -> Review -> Confirm。此示例,也可适用于 AI 流程等用户输入。
1、定义订单状态
@Data
@AllArgsConstructor
public static class OrderState {
String orderId;
String draftContent;
boolean isApproved;
String finalMessage;
}
2、定义节点任务组件
- Draft 起草
public class Draft implements TaskComponent{
@Override
public void run(FlowContext ctx, Node n) throws Throwable {
OrderState state = ctx.getAs("state");
String draft = "订单 " + state.getOrderId() + " 的销售合同草稿已生成,总价 $10000,请审核。";
System.out.println("Node 1: [生成草稿] 完成,内容: " + draft);
state.setDraftContent(draft);
}
}
- Review 审计
public class Review implements TaskComponent{
@Override
public void run(FlowContext ctx, Node n) throws Throwable {
OrderState state = ctx.getAs("state");
if (!state.isApproved()) {
System.out.println("Node 2: [人工审核] 订单草稿需要人工确认。");
ctx.stop();
} else {
System.out.println("Node 2: [人工审核] 已通过外部系统确认,继续流程。");
}
}
}
- Confirm 确认
public class Confirm implements TaskComponent{
@Override
public void run(FlowContext ctx, Node n) throws Throwable {
OrderState state = ctx.getAs("state");
String finalMsg = "订单 " + state.getOrderId() + " 流程已完成,合同已发送。";
System.out.println("Node 3: [最终确认] " + finalMsg);
state.setFinalMessage(finalMsg);
}
}
3、构建流图并运行和测试
为方便测试,下面使用硬编码方式。平常建议使用 yaml 编排(更适合所有角色:开发、测试、运维,领导)。
@Slf4j
public class DemoTest {
//流引擎
FlowEngine flowEngine = FlowEngine.newInstance();
//不阻塞状态控制(如果不手动中断或停止,则一直往下流)
NotBlockStateController stateController = new NotBlockStateController();
//内存节点状态存储
InMemoryStateRepository stateRepository = new InMemoryStateRepository();
@Test
public void case1() {
//硬编码构建流图,方便测试
Graph graph = Graph.create("demo1", decl -> {
decl.addActivity("n1").task(new Draft()).linkAdd("n2");
decl.addActivity("n2").task(new Review()).linkAdd("n3");
decl.addActivity("n3").task(new Confirm());
});
//初始化订单装态
OrderState initialState = new OrderState("o-1", null, false, null);
FlowContext context = FlowContext.of(initialState.getOrderId(), stateController, stateRepository)
.put("state", initialState);
//::第一次执行
StateResult result = null;
result = flowEngine.forStateful().eval(graph, context);
assert result.getState() == StateType.WAITING; //在 n2 时被停止了
Assertions.assertEquals("n2", result.getNode().getId());
//模拟人工审核
initialState.setApproved(true);
//::第二次的执行
result = flowEngine.forStateful().eval(graph, context);
assert result.getState() == StateType.COMPLETED; //一路到底(n2->n3)
Assertions.assertEquals("n3", result.getNode().getId());
}
}
4、运行效果
