接 FlowCore - SaaS 快速开发套件之工作流引擎
FlowCore 发布之后,我着手做一个 BPM/OA 的 Gem,也就是之前提的 FlowKit,做的过程中发现了一些问题非常卡手,所以我决定根据实践过程中的问题改进一下。
其中最大的问题在于两点:
我发现在 PetriNet 这一层并不容易解决这些问题,并且我和一些人沟通的过程中发现理解 PetriNet 概念并不容易,所以我希望能够尽可能的屏蔽他,于是我引入了一层新的抽象 —— Pipeline。
当然这并不是我否定了 PetriNet, Pipeline 和 PetriNet 的关系类似 ActiveRecord 和 Arel,AR 的查询界面实际上是对 Arel 的包装,为了易用性并没有充分暴露 Arel 的全部功能,绝大多数情况下 AR 提供的功能足矣,极端复杂的情况下可以绕过 AR 直接使用 Arel,但是此时要自行承担风险。
Pipeline 牺牲了一些表达能力下换来了:
步骤(Step)
一种元素编辑好的 Pipeline 可以被编译成 PetriNet,用于真正的执行。
我以组织大会拉赞助的流程(实际不是这样子的哈~)为例:
编辑器(使用 GraphViz 绘制出来的):
预览图:
最终会编译到 PetriNet
很直观吧?也不用了解 PetriNet 的那些规则了。
Pipeline 的步骤(Step
)被设计成可利用 STI 扩展的,但是核心有五种步骤类型:
Task
):执行业务逻辑的节点Exclusive Choice
):类似编程语言的 if...elsif...else
,如果有满足条件的分支则跳入,否则会进入默认分支,圆角矩形为分支,分支可附着条件(Guard
)Parallel Split
):同时执行多个分支的逻辑,当所有分支的步骤都执行完后,才会继续Redirection
):跳转到其他节点,实现类似驳回后订正然后重新提交的流程。End
):跳转到结束流程只有 跳转
有特别规则:
barrier_step
,当前只有 并行分支
是),不能跳转到屏障外的步骤去,否则业务上就说不通了当然也不用特别记,这些规则实现在代码里了,包括在配置界面上也只能选择有效的步骤进行。
我已经翻新了 Dummy 应用,把半成品 FlowKit 塞了进去,可以玩玩,但是还有很多工作没完成,后边要准备 RubyConf 了,所以先把最近的成果放出来。
我主要是想把想法先给实现出来然后验证,做到一半发现一些开始的设计可能有问题, 如果有兴趣研究或者采用的话,我有一些地方需要帮助:
数据库表设计需要优化
Pipeline 由 Pipeline
、Step
、Branch
三个模型组成,大致可描述为:
Step
(多分支步骤)可以有多个 Branches
Step
(如果在一个分支内)属于一个 Branch
Branch
有多个 Steps
Step
自身也是一个树状结构,使用 ancestry
gem 维护Step
的顺序由 acts_as_list
维护表的设计以及查询的使用应该有优化空间
编译到 PetriNet 的代码有很大优化空间
入口代码:https://github.com/rails-engine/flow_core/blob/master/app/models/flow_core/pipeline.rb#L21
这段代码我测试过,虽然正确工作(几乎吧),但是我自己并不满意。
困难点在于,Step
编译出来的 PetriNet 片段,结尾有可能是 Place
或者 Transition
,同时 Step
跟 Step
产生的 PetriNet 片段要连接,这里就有很多种可能的情况要处理了。
处理步骤的移动
比如 跳转节点 的移动是有规则的,所以得提供个 move
方法去处理移动,以及暴露可以移动到哪些步骤的前或后
GraphViz 的可视化排版并不美观,绘制代码比较乱
我使用 GraphViz 主要是因为不会写前端...而且前端工作量太大
其他我没想到的点
欢迎给出意见或者问题...