任务触发器
任务触发器,它可以触发或启动一个特定的流程、操作或事件序列。
- 立即触发
当执行到触发器节点,会立刻执行触发器实现类业务,结束执行进入下一个节点。
- 定时触发
当执行到触发器节点,会在数据库
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()));
});
}
}