节点任务、连接条件和驱动器定制
solon-flow 采用开放式架构
- 节点“任务”与连接“条件”的描述没有固定格式,是由 ChainDriver 的处理决定
- 使用哪个 ChainDriver 就采用哪种格式描述
就像 jdbc 的 Driver, mysql 和 pgsql 的语法各不同。
1、默认格式(SimpleChainDriver 方案,框架内置)
示例 | |
---|---|
任务描述 | @t (任务组件风格) 或者 context.result=1; (java 脚本风格) 或者 #c12 (链调用风格) |
条件描述 | @c (条件组件风格) 或者 user_id > 12 (java 脚本表达式风格) |
- 组件风格
以@
开头,表过调用对应名字的组件。
@Component("t") //任务组件
public class TaskComponentT implements TaskComponent {
@Override
public void run(ChainContext context, Node node) throws Throwable {
}
}
@Component("c") //条件组件风
public class ConditionComponentC implements ConditionComponent {
@Override
public boolean test(ChainContext context, NodeLink link) throws Throwable {
return false;
}
}
- 脚本风格
SimpleChainDriver 的脚本能力,由 Liquor 提供。
- 跨链调用
以#
开头,表示调用引擎实例内的对应id的链。通过定制,也可对接 solon faas 的能力。
2、定制格式参考(RubberChainDriver 方案,第三方的)
示例 | |
---|---|
任务描述 | F,tag/fun1;R,tag/rule1 (dsl 风格) |
条件描述 | m.user_id,>,12,A;m,F,$ssss(m),E (dsl 风格) |
3、驱动器定制参考
本示例,模拟有状态的审批型流程(一般,计算型的不需要定制)。仅供参考
@Component
public class ApproveChainDriver extends SimpleChainDriver {
@Inject
FlowService flowService;
@Override
public void handleTask(ChainContext context, Task task) throws Throwable {
if (tryIfChainTask(context, task)) {
//如果跨链调用
return;
}
if (tryIfComponentTask(context, task)) {
//如果用组件运行
return;
}
String instance_id = context.param("instance_id");
String role = context.param("role");
String chain_id = task.node().chain().id();
String task_id = task.node().id();
//通过数据库查找状态(或者,把状态批量加载到上下文参考)
TaskState taskState = flowService.getState(instance_id, task_id);//查询任务装态
if (taskState == null) {
//中断(流,不会再往下驱动),等用户操作出状态
context.interrupt();
//如果当前用户匹配这个节点任务
if(role.equals(task.node().meta().get("role"))){
//则把这个节点,作为结果(用于展示界面)
context.result = task.node();
}
}
}
}
定制驱动器的应用
@Component
public class DemoCom {
@Inject
FlowEngine flowEngine;
@Inject
ApproveChainDriver approveChainDriver;
public void test() throws Exception {
ChainContext context = new ChainContext(approveChainDriver);
context.paramSet("instance_id", "1");
context.paramSet("user_id", "2");
context.paramSet("role", "lead");
flowEngine.eval("c1", context);
//获取结果节点
Node node = (Node)context.result;
//构建操作节点界面...
}
}
附:驱动器接口
内置的基础实现 SimpleChainDriver,定制时可以以它为基础。
@Preview("3.0")
public interface ChainDriver {
/**
* 节点运行开始时
*/
void onNodeStart(ChainContext context, Node node);
/**
* 节点运行结束时
*/
void onNodeEnd(ChainContext context, Node node);
/**
* 处理链接条件
*/
boolean handleCondition(ChainContext context, Condition condition) throws Throwable;
/**
* 处理执行任务
*/
void handleTask(ChainContext context, Task task) throws Throwable;
}