2 个版本
0.1.4 | 2023年1月3日 |
---|---|
0.1.0 | 2022年11月23日 |
#14 在 #property
250KB
6.5K SLoC
姚工作流引擎
yao
是一个快速、小巧、可扩展的工作流引擎,它提供了基于简单的 yml 模型的执行工作流的能力。
yml 工作流模型与传统流程(如 bpmn)不同。它受到 Github actions 的启发。作为对比,它增加了分支定义以支持更复杂的流程,为了业务审批流程,它在步骤中定义了 subject
属性以支持用户、组织和角色的顶级绝对规则。
快速
使用 Rust 创建库,没有虚拟机,没有数据库依赖。默认存储使用 rocksdb 进行本地存储。
小巧
库的大小仅为 3MB(不包含本地数据库)
可扩展
支持插件来扩展功能
示例
以下是一些示例
如何启动
首先,您应该加载一个 ymal 工作流模型,并调用 engine.start
来启动,并调用 engine.close
来停止它。
use yao::{Engine, Vars, Workflow};
#[tokio::main]
async fn main() {
let engine = Engine::new();
let text = include_str!("../examples/simple/model.yml");
let mut workflow = Workflow::from_str(text).unwrap();
let mut vars = Vars::new();
vars.insert("input".into(), 3.into());
workflow.set_env(vars);
engine.push(&workflow);
let e = engine.clone();
engine.on_workflow_complete(move |w: &Workflow| {
println!(
"on_workflow_complete: {:?}, cost={}ms",
w.outputs(),
w.cost()
);
e.close();
});
engine.start().await;
}
如何创建模型
注意 yaml 的结构,有不同类型的节点,由 Workflow
、Job
、Branch
和 Step
构建。每个工作流可以有更多作业,每个作业可以有更多步骤,每个步骤可以有更多分支,并且分支可以有 if
属性来判断条件。
可以在每个节点中设置 env
属性,在 run
脚本中,您可以使用 env
模块来获取(env.get
)或设置(env.set
)值。
run
属性是基于 rhai 脚本的。
name: model name
jobs:
- id: job1
env:
value: 0
steps:
- name: step 1
run: |
print("step 1")
- name: step 2
branches:
- name: branch 1
if: ${ env.get("value") > 100 }
run: |
print("branch 1");
- name: branch 2
if: ${ env.get("value") <= 100 }
steps:
- name: step 3
run: |
print("branch 2")
在 Workflow
中,您可以设置 outputs
来输出可用的环境。
name: model name
outputs:
output_key:
jobs:
- id: job1
steps:
- name: step1
run: |
env.set("output_key", "output value");
subject
用于创建用户 [Act
],它可以等待用户调用 post_message
完成操作。
name: model name
jobs:
- id: job1
steps:
- name: step1
subject:
matcher: any
users: |
let a = ["u1"];
let b = ["u2"];
a.union(b)
它将根据子用户自动生成用户操作并发送消息。当您向工作流发送 post_message
时,matcher 告诉工作流如何传递步骤操作,有几个匹配规则。
- matcher
-
one 仅生成或检查一个用户
-
any 用于匹配任何用户
-
some(rule_name) 通过提供规则名称来匹配一些用户,该规则名称可以通过
register_some_rule
函数进行注册。 -
ord 或 ord(rule_name) 通过提供规则名称逐个生成活动消息,该规则名称可以通过
register_ord_rule
函数进行注册。
- users 用于生成步骤参与者,最终结果是用户 ID,这些 ID 可以通过 org 或 role 规则生成。
以下代码 role("test_role")
使用规则来获取角色 test_role
中的用户。
users: |
let users = role("test_role");
users
以下代码使用 user("test_user")
获取用户,然后通过 relate
规则找到部门的用户拥有者(d.owner
)。
users: |
let users = user("test_user").relate("d.owner");
users
使用构建器创建模型
use yao::{Workflow};
let mut workflow = Workflow::new()
.with_name("workflow builder")
.with_output("result", 0.into())
.with_job(|job| {
job.with_id("job1")
.with_env("index", 0.into())
.with_env("result", 0.into())
.with_step(|step| {
step.with_id("cond")
.with_branch(|branch| {
branch
.with_if(r#"env.get("index") <= env.get("count")"#)
.with_step(|step| {
step.with_id("c1")
.with_action(|env| {
let result =
env.get("result").unwrap().as_i64().unwrap();
let index = env.get("index").unwrap().as_i64().unwrap();
env.set("result", (result + index).into());
env.set("index", (index + 1).into());
})
.with_next("cond")
})
})
.with_branch(|branch| {
branch.with_if(r#"env.get("index") > env.get("count")"#)
})
})
.with_step(|step| {
step.with_name("step2")
.with_action(|env| println!("result={:?}", env.get("result").unwrap()))
})
});
注册插件
请参阅 ActPlugin
的示例。
注册存储适配器
请参阅 StoreAdapter
的示例。
注册组织适配器
请参阅 OrgAdapter
的示例。
注册角色适配器
请参阅 RoleAdapter
的示例。
注册规则适配器
请参阅 RuleAdapter
的示例。
依赖项
~76MB
~1.5M SLoC