Solon v3.8.3

flow - 中断、持久化与恢复

</> markdown
2026年1月13日 下午8:44:47

在实际业务中,许多流程不是一次性执行完的。例如:

  • 条件不满足而中断:流程流转到某一节点,因前置业务状态未就绪(如余额不足、等待第三方支付确认)而需要临时中断。
  • 异步事件驱动:流程运行到中途需要等待外部系统推送消息(如回调信号)才能继续。
  • 状态机流转:将复杂的业务逻辑拆解为多个阶段,每个阶段完成后进行持久化。

solon-flow 通过 FlowContext 的 执行跟踪 (Tracing) 和 快照序列化 (Snapshot) 能力,轻松实现流程的“原地休眠”与“唤醒执行”。

1、核心机制

  • 中断控制:在任务执行器(Task)中调用 context.stop(),引擎会停止向下流转。
  • 状态持久化:使用 context.toJson() 将当前的执行进度、变量数据序列化。
  • 状态恢复:通过 FlowContext.fromJson() 重建上下文,调用 flowEngine.eval() 引擎会自动从上次中断的节点继续执行。

2、示例代码

结合上下文(FlowContext)的 “中断或停止控制” 和 “持行跟踪与(快照式)序列化”能力,展示停止与恢复示例:

public class StopAndResumeDemo {
    @Test
    public void csae1() {
        //构建测试图(方便测试)
        Graph graph = Graph.create("g1", spec -> {
            spec.addStart("n1").linkAdd("n2");

            spec.addActivity("n2").task((ctx, n) -> {
                System.out.println(n.getId());
            }).linkAdd("n3");

            spec.addActivity("n3").task((ctx, n) -> {
                if (ctx.getOrDefault("paas", false) == false) {
                    ctx.stop();
                    System.out.println(n.getId() + " stop");
                } else {
                    System.out.println(n.getId() + " pass");
                }
            }).linkAdd("n4");

            spec.addEnd("n4");
        });

        FlowEngine flowEngine = FlowEngine.newInstance();
        FlowContext context = FlowContext.of("c1");

        flowEngine.eval(graph, context);

        //1.因为条件不满足,流程被停止了
        Assertions.assertTrue(context.isStopped());
        Assertions.assertFalse(context.lastRecord().isEnd()); //还没到最后结点

        //保存当前状态(存入数据库)
        String snapshotJson = context.toJson();

        //2.几天之后。。。(条件有变了)从数据库中取出状态
        context = FlowContext.fromJson(snapshotJson);
        context.put("paas", true); //加入新条件
        flowEngine.eval(graph, context);

        Assertions.assertFalse(context.isStopped()); //没有停止
        Assertions.assertTrue(context.lastRecord().isEnd()); //到最后结点了
    }
}