一个对话管理或者是什么其他工作流都是存在流转过程的,这个流转的过程是比较重要的。一个清晰的流转方式会极大的简化开发方式。这是Opendial中三个重点的第一个,三个分别是
- 流程
- 条件判断
- 填槽和赋值
流转
在Opendial中采取流转的方式是每次是否有新的变量产生 && 新的变量是否触发了Model的变更。
- 在流程中是否产生了新的变量,如果没有新变量的产生,本次流程触发执行完毕。
- 是否有Model监听了新的变量。
虽然在这里使用了 监听
这个概念,但是实际上在Opendial源码中是使用for循环来遍历的,这个变量是否触发了某一个Model,这个触发的机制也比较简单,就是变量是否等于Model的 trigger
触发器。用监听来描述会更好的理解整个过程. 但是并没有监听的内在逻辑。
example:
<domain>
<model id="model0" trigger="first">
<rule>
<case>
<effect>
<set var="subState" value="world!!"/>
</effect>
</case>
</rule>
</model>
<model id="model2" trigger="subState">
<rule>
<case>
<effect>
<set var="gw" value="hello {subState}"/>
</effect>
</case>
</rule>
</model>
</domain>
在运行的过程中,输入的变量 `first` 会触发 `model0` 的执行,在执行的过程中将subState赋值为 `world!!` , 等同于执行了 `String subState="hello"` 这行语句,Model0执行完以后,系统发现有了新的变量 `subState`, 于是又开始跑model的for循环,发现model2匹配,于是触发 `model2` 的执行。
最后可以在输出结果中获取 gw
变量的数据,就是 hello world!!
.
总结
在 Opendial
中流程是采用变量更新的方式去触发Model的,第一次触发的方式需要外部携带变量进来。用了一个简单的例子描述了流转过程,例子很简单,只涉及到简单的变量,不涉及到函数,以及函数赋值,例如在函数中调用Dubbo服务,调用Http等等,在将返回结果输出到流程的上下文中也是可以的。
在审批流中,并不是实时审批的,可以针对审批结果进行Model的监听
- A发起审批工作
- 进入审批流程,进入了分支B,结束
- 老板审核完成,回调进入流程。
触发的方式有千千万万种,但是不能拘泥在某一种特定的实现思路中。只要流程能触发,无论怎么操作都可以的。
在B的判定中,可能需要人来审核,因为存在实时性的问题,这个流程会暂停在B,等待结果。同理C也是如此,这种方式,我们只需要重新从A跑一次流程即可,但是需要保证整个过程的幂等机制,只有B/C给出返回结果的时候才能继续向下跑流程。
在审批不通过和审批通过的时候,都可以使用回调的形式来重新触发执行A,由于幂等机制,只要是同一个流程,无论跑多少次,都是同一个结果。