Skip to content
广告❤️成为赞助商

任务触发器

任务触发器,它可以触发或启动一个特定的流程、操作或事件序列。

  • 立即触发

当执行到触发器节点,会立刻执行触发器实现类业务,结束执行进入下一个节点。

  • 定时触发

当执行到触发器节点,会在数据库 flw_task 中记录一条待执行记录,期望任务完成时间expireTime到达后由定时器触发执行,结束后进入下一个节点。

实例配置

触发器节点模型

json
{
    "nodeName": "延时触发器",
    "type": 7,
    "extendConfig": {
      "time": "7:d",
      "args": "执行 json 参数",
      "trigger": "test.mysql.TaskTriggerImpl"
    }
}

实现触发器接口

接口定义,实现类需要注入到 Spring 容器中。

java
public interface TaskTrigger {

    /**
     * 执行任务触发器节点
     *
     * @param nodeModel 节点模型
     * @param execution 执行对象
     * @param finish 执行完成函数【必须执行否则无法继续执行下一步】
     */
    boolean execute(NodeModel nodeModel, Execution execution, Supplier<Boolean> finish);
}

同步执行

触发器实现类返回 true 表示执行完成,执行完成后进入下一步。

java
public class TaskTriggerImpl implements TaskTrigger {

    @Override
    public boolean execute(NodeModel nodeModel, Execution execution, Function<Execution, Boolean> finish) {
        System.out.println("执行了触发器 args = " + nodeModel.getExtendConfig().get("args"));
        return finish.apply(execution);
    }
}

异步执行

触发器实现类可以异步执行任务,执行完成后调用触发器完成函数结束执行。异步调用可以应用在某些场景下,比如执行耗时操作。

java
@Component
public class FlowTaskTrigger implements TaskTrigger {

    @Override
    public boolean execute(NodeModel nodeModel, Execution execution, Function<Execution, Boolean> finish) {
        CompletableFuture.runAsync(() -> asyncExec(execution, finish));
        System.out.println("FlowTaskTrigger = " + nodeModel.getNodeName());
        return true;
    }

    public void asyncExec(Execution execution, Function<Execution, Boolean> finish) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("进入异步调用完成触发器完成函数");
            finish.apply(execution);
        }
    }
}

暂存执行

该场景应用在当触发器需要执行一个非常耗时的业务逻辑时,需要让流程停留在当前状态且不堵塞影响其它任务执行,待耗时业务执行完再回调流程完成触发器任务进入下一个节点。

java
@Component
public class FlowTaskTrigger implements TaskTrigger {

    @Override
    public boolean execute(NodeModel nodeModel, Execution execution, Function<Execution, Boolean> finish) {
        // 设置为 true 流程不会继续执行进入下一节点,触发器任务为暂存状态。
        execution.setSaveAsDraft(true);
        boolean ok = finish.apply(execution);
        if (ok) {
            FlwTask flwTask = execution.getFlwTask();
            if (null != flwTask) {
                Long flwTaskId = flwTask.getId();
                // 触发器任务ID保存到业务中,待业务执行完成调用 flowlongEngine.executeFinishTrigger 执行完成触发器任务,继续执行流程进入下一个节点。
                System.out.println("触发器任务ID = " + flwTaskId);
            }
        }
        return ok;
    }
}

测试用例

测试用例源码位置 flowlong-spring-boot-starter/src/test/java/test/mysql/TestTrigger.java

java
public class TestTrigger extends MysqlTest {

    @BeforeEach
    public void before() {
        processId = this.deployByResource("test/testTrigger.json", testCreator);
    }

    @Test
    public void test() {
        flowLongEngine.startInstanceById(processId, testCreator).ifPresent(instance -> {

            // 忽略查询时间执行定时器任务
            this.executeActiveTasks(instance.getId(), flwTask ->

                    // 模拟自动完成定时触发器任务
                    flowLongEngine.autoCompleteTask(flwTask.getId()));

            this.executeActiveTasks(instance.getId(), flwTask ->

                    // 进入人事审批
                    Assertions.assertEquals("人事审批", flwTask.getTaskName()));
        });
    }
}

更适合中国人的工作流引擎