介绍camunda 工作流 核心引擎 之 流程实例模型 (翻)

 
原文地址: http://camundabpm.blogspot.com/2013/06/introducing-activity-instance-model-to.html
 
camunda引入了活动实例和活动实例树的概念,这篇文章目的是分析引擎内部,描述实例行为的实现.
 

为什么我们需要一个活动的实例树?

流程实例树中的每个活动实例都包含有一个节点,有些活动实例是有范围的(如嵌入式子流程) 。这种范围的活动实例可能包含有子实例:
 

流程实例树及范围
                                                                                                 流程实例树及范围
 
      到目前为止,一切都很好。但是不是由流程引擎来执行实例树呢?在一定程度上是的,但不是在所有情况下。有众多的情况下,树的执行并没有按照BPMN 2.0的规范来 。

 

 

作用域与并发

 

流程引擎为作用域和并发提供了“子执行(child execution)”的概念。如果一个非并发(non-concurrent)执行到达并行网关,它会呆在那里,为每个顺序流催生出并发子执行(concurrent child executions )。其效果是,子执行将会嵌套在并行网关(fork)分叉处的一个非活动执行下。这个概念是一个内部的实现细节,而不是BPMN 2.0规范,流程初学者一般很难理解.

 



 
在执行树(左边) ,你会看到一个无效的范围执行(inactive scope execution)在并行网关处等待(即使流程实例已经完成,活动任务正在执行服务任务(service task)) 。正在执行服务任务(service task)的执行(executions)嵌套属于等待于并行网关fork(分叉)处的无效范围执行(inactive scope execution )。在活动实例树(右侧) ,无效范围执行是不可见的。

 

在活动实例树,根节点代表流程实例本身(即流程定义节点(process)的实例)并且其子实例表示为正在进行的服务任务活动实例.

 

 

另一个例子是并行多实例。参考下面的例子:

1) 单个并行多实例任务:

 

 

 

 

 2) 多实例子流程:

 



 

 

 在左边的图中,流程引擎根据内部流程定义等因素产生额外的执行(结合上上个图)。在流转过程中,我们希望更形象化活动实例树,这样更容易理解也更符合BPMN 2.0 规范。

 


执行树的压缩和优化

 
引入活动实例树的第二个原因是,流程引擎运行时压缩和优化执行树。考虑一个并行网关有两个usertasks的例子。最初T1和T2都是活动的。在执行树中,我们将看到无效的并发根执行等待在并行网关,为每个任务之一。活动实例树具有相同的结构,但根节点对应的流程实例本身,并且它并不等待在并行网关.  当T2完成任务后,将压缩流程引擎执行树,去除T1的执行,并用根执行取代它。如果执行T1引用了变量或任务,那么它们将被移动到根执行中。活动实例树看起来不同的是:它仍然包含一个T1的活动实例和流程定义本身。

 

 

 

                                                                                                压缩执行树

 

这种行为(behavior)的衍生,在执行树种并不存在"节点实例标识"(activity instance identity) 这种概念.  没有唯一标识来描述一个节点的实例。在一般情况下,是无法保证同一个进入节点实例执行将会完全一致的完成它。例如: 在上面的例子中T1 是以执行ID=2开始 以执行ID=1结束。

 

注: 节点实例 即 活动实例  , 这里翻译成节点.更容易理解! 

 

(顺便说一句 : 这就是为什么一般,你永远不应该使用消息相关的执行的ID(execution IDs) )

 

 

在流转过程中,我们希望允许用户可以选择节点实例和查看详细信息 例如:(variables,tasks ...) 。如果我们使用执行IDS(execution Ids) 可能会出现以下行为:当他正在查看详细信息的时候, 用户选择T1 ,然后URL中写入的是执行ID( execution id)。 这个时候, T2完成了,然后执行树被流程引擎压缩了。现在,用户刷新浏览器 。将会得到一个错误,因为他先前选定的执行ID不存在了,即使当前任务仍然是活动的。哎,做人真失败!

 

(更糟糕的是:他可能将这个错误的url发给了更多的同事。 )

 

 

 

统一历史和执行的模型

 

 

流程引擎添加活动实例树的第三个原因是,它能更好的配合工作流程引擎历史的工作。工作流引擎历史中,我们总是需要有历史活动实例的概念。将历史和运行树关联起来,允许我们使用相同的客户端代码更形象的表示历史活动实例和活动。此外:流转过程也同样适用,即使历史关闭了。

 

 

 

活动实例树是如何实现的

 

将活动实例树压进执行树种. 我们给执行数据表新增一列 (ACT_INST_ID_) :

 

 

 

                                                             新列 ACT_INST_ID_ 被添加到 执行数据表中

 

 

 除了改变数据库外,没必要更改任何东西. 其他所有列的值保持不变,和以前一样,有同样的执行数目。

 

 

活动实例 IDs 通过AtoMic Operations 生成, 譬如: start/end 活动:

 

 

 

 

 

这里个测试用例,验证活动实例ID生成和活动的 (开始/结束监听器)的调用如期运行(活动实例ID的生成早于活动start监听被触发 ) 。

 

 

 

 

如何检索活动的实例树?

 

 目前检索活动实例树只能通过一个整体流程实例。

 

使用JAVA API:

 

 

ActivityInstance rootActivityInstance = runtimeService.getActivityInstance(pi.getProcessInstanceId());

 

 

 

也可以使用rest api

 

下一步,我们将推出公共API对活动实例等查询的支持。

 

 

executions  确实要被废弃不能用么?

 

我不知道,但我的直觉是肯定的。 “执行”的概念,是一个专有的流程内部引擎需要关注的,并且活动实例模式将逐渐被取代。这可能会是我们将要往下走的道路,你仍然可以执行查询,但事实上,你会得到活动实例作为结果而不是执行实例.

 

 

展开阅读全文

没有更多推荐了,返回首页