Gem WorkflowCore —— SaaS 快速开发套件之工作流引擎

jasl · 2018年09月27日 · 最后由 zzz6519003 回复于 2018年10月10日 · 127 次阅读
本帖已被设为精华帖!

前言:今年个人遇到了一些私事没有办法拿出足够精力组织 RubyConf China,最近做出一个比较重要的人生决定再次下场创业,在进入创业、办会两边倒之前下定决心抽了一周时间把一直想做的轮子组的最后一块拼图也是最难的一块搞出来,便是接下来要介绍的工作流引擎。

实际上我发现把工作流引擎做完善并且演示出来是一个非常耗费精力的需要长时间投入的工作,所以不像我之前完成的开源项目,我决定把这个刚完成技术验证的版本公开,露一露怯。

项目地址: https://github.com/rails-engine/workflow_core

工作流引擎可以说是企业信息系统的核心技术,用于解决审批流程的定义和流转。此外,IFTTT 类型的应用,包括苹果 iOS 12 的新功能 Shortcut,也都是由工作流引擎驱动,在数据处理领域也可以考虑使用。

虽然我们总是说 Ruby 或者说 Rails 开发效率高,但是对于复杂的信息系统而言,缺乏领域相关的基础设施使得 Ruby on Rails 并不会比 Java、C# 等传统技术有优势。相反,由于没有标准实践,大多数团队没有技术驱动业务的思维,导致基于 Ruby 的信息系统反而在可维护性上表现极差。

我认为,企业信息系统的三个关键组件为:动态表单、角色权限、流程,流程承载动态表单的数据(Payload),交给合适的角色来处理,这就是我造这三个轮子的动机。 注:表单只是工作流的一种 Payload,以此便可以解开表单引擎和工作流引擎的耦合

WorkflowCore 采用了比较经典的 PetriNet 数据结构实现,准确的说是基于 PetriNet 的一个为工作流优化的特殊型式 Workflow Net (个人推荐读读这个博客的相关文章),它能够表达几乎一切可能的流程流转方式,包括 BPMN 等业内标准规范的流程定义都是 PetriNet 的子集,简单介绍一下,PetriNet 是一个有向图,里面涉及了几个概念:

  • 圆形图示 Place:流程流转过程中的稳定状态
  • 矩形图示 Transition:造成状态改变的动作
  • 黑点图示 Token:待处理的任务,一个工作流里可以包含多个活跃的 Token

并且 Workflow net 有一个特性,如上图所示,工作流由 Place 开始,由 Place 结束,Place 之间不能相邻,必须是 Transition。

综合这些,我们就很容易设计出工作流引擎的核心了,这正是 WorkflowCore 所做的事:

  • 设计了 PetriNet 相关概念的模型
  • 为 Transition 定义了 fire(token) 方法作为接口

就这样简单,那么如何实现工作流的流转呢?只需要实现自己的 Transition 类型,覆写 fire(token) 方法,在其中编写当前的 Token 要如何销毁,新的 Token 要如何创建,结束~ 如果你需要一些比较特殊或者需要做比较脏的逻辑,这些代码都会封装在某一个 Transition 子类中,不会污染到其他地方,此外,Token 的创建销毁是无副作用的,也不用担心特殊的逻辑对流程有影响,但是如果流转过程对工作流外的资源操作了,这会产生 side-effect 需要自行考虑会不会对系统造成影响哈。

当然,实际作为 Gem,迁移操作要做到原子化,包括可能的嵌套事务的坑的避免,所以还是有一些琐碎的技术工作在其中的。

和之前的 Gem 一样,项目的 dummy app 提供了一套测试应用,展现的是一套审批系统,使用方法可以自行看 Readme 注:需要提前安装下 Graphviz

另外,dummy app 里使用了另一个未完成的组件 —— 基于 mRuby 的表达式执行沙箱 ScriptCore ,填过业务系统的坑的人一定都经历过解决极端复杂的条件的情况,一个几乎完整的 Ruby 执行环境应该足够解决绝大多数的复杂场景了,并且能够保证安全性和控制资源使用(不必担心死循环等情况)。遗憾的是,由于 mRuby 并没有原生的 BigDecimal,也没有 Date,Datetime 的行为和 MRI 也不一致(主要是时区方面),所以完全释放潜力还是需要做一些努力的,但这套思路是可行的,这套思路由 Shopify 提出,参见 Shopify Script

最后,由于精力所限,看样子我只能拿出一个预览版本的了,有类似经验或者需求的朋友欢迎交流,Readme 里我列出了一些需要确认的点或要填的坑。

共收到 19 条回复

非常感谢姜军,为我这方面相关开发提供了很多思路💓

很早就耳闻了,终于放出来了,赞一个~ (最近一段时间一直忙家里的事情,代码一直没有看,捂脸)

qhwa 回复

其实就是上周才动手写的 😂

表单只是工作流的一种 Payload,以此便可以解开表单引擎和工作流引擎的耦合 👍

回忆起来才发现第一个活就跟工作流打交道了,而且当初用户权限认证还用的是LDAP来做,😂 😂 😂

huacnlee 将本帖设为了精华贴 09月27日 12:26

上周才开始写的代码 很高效啊 👍

利害。基于java的那几个工作流引擎,都是一个团队在做

放出来啦,赞!

指不定后面就要用到,支持一波!

zouyu 回复

java的是哪个

jdshi 回复

jbpm activiti

lyfi2003 回复

好啊,用得时候有什么问题建议随时骚扰

关注好久了。研究下怎么在前后分离的情况下,配合graphql使用

kimmg 回复

这个触发流转动作没难度,表单这块 @hooopo 去年就在他们那用上了,前后端分离+GraphQL (他欠了我很多稿子

终于来了

学习了

早日开发出你的游戏引擎hhhh

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册