一个对话管理或者是什么其他工作流都是存在流转过程的,这个流转的过程是比较重要的。一个清晰的流转方式会极大的简化开发方式。这是Opendial中三个重点的第一个,三个分别是

  • 流程
  • 条件判断
  • 填槽和赋值

流转

在Opendial中采取流转的方式是每次是否有新的变量产生 && 新的变量是否触发了Model的变更。

  • 在流程中是否产生了新的变量,如果没有新变量的产生,本次流程触发执行完毕。
  • 是否有Model监听了新的变量。

虽然在这里使用了 监听 这个概念,但是实际上在Opendial源码中是使用for循环来遍历的,这个变量是否触发了某一个Model,这个触发的机制也比较简单,就是变量是否等于Model的 trigger 触发器。用监听来描述会更好的理解整个过程. 但是并没有监听的内在逻辑。

example:

  1. <domain>
  2. <model id="model0" trigger="first">
  3. <rule>
  4. <case>
  5. <effect>
  6. <set var="subState" value="world!!"/>
  7. </effect>
  8. </case>
  9. </rule>
  10. </model>
  11. <model id="model2" trigger="subState">
  12. <rule>
  13. <case>
  14. <effect>
  15. <set var="gw" value="hello {subState}"/>
  16. </effect>
  17. </case>
  18. </rule>
  19. </model>
  20. </domain>
  1. 在运行的过程中,输入的变量 `first` 会触发 `model0` 的执行,在执行的过程中将subState赋值为 `world!!` 等同于执行了 `String subState="hello"` 这行语句,Model0执行完以后,系统发现有了新的变量 `subState` 于是又开始跑modelfor循环,发现model2匹配,于是触发 `model2` 的执行。

最后可以在输出结果中获取 gw 变量的数据,就是 hello world!! .

总结

Opendial 中流程是采用变量更新的方式去触发Model的,第一次触发的方式需要外部携带变量进来。用了一个简单的例子描述了流转过程,例子很简单,只涉及到简单的变量,不涉及到函数,以及函数赋值,例如在函数中调用Dubbo服务,调用Http等等,在将返回结果输出到流程的上下文中也是可以的。

在审批流中,并不是实时审批的,可以针对审批结果进行Model的监听

  • A发起审批工作
  • 进入审批流程,进入了分支B,结束
  • 老板审核完成,回调进入流程。

    触发的方式有千千万万种,但是不能拘泥在某一种特定的实现思路中。只要流程能触发,无论怎么操作都可以的。

image.png

在B的判定中,可能需要人来审核,因为存在实时性的问题,这个流程会暂停在B,等待结果。同理C也是如此,这种方式,我们只需要重新从A跑一次流程即可,但是需要保证整个过程的幂等机制,只有B/C给出返回结果的时候才能继续向下跑流程。

在审批不通过和审批通过的时候,都可以使用回调的形式来重新触发执行A,由于幂等机制,只要是同一个流程,无论跑多少次,都是同一个结果。