Solon v3.7.2

场景4:长计算的暂停与恢复

</> markdown

设计一个简单的,由三个节点组成的流程: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、运行效果