工作流调度算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
工作流调度算法
作者:qwerty | 源自:原创 | 发表日期:2007-4-14 | 阅读次数:242 | 【保存文章至硬盘】【打印文章】
主要比较:OBE,Shark,OSWorkflow,jBpm。分析一下他们的调度算法,就基本上可以知道其能力有多强。
OBE 的引擎调度机制
说到开源引擎,首先就要说一下OBE,这是最早一款支持XPDL 的开源工作流引擎。可惜由于没有良好的持续维护,到如今,虽然Adrian 依然还在对其进行一些补充和修改,但已经掩饰不出其“落寞”的容颜了
(/james999/category/57982.aspx)。
OBE 的引擎运转调度算法是很简单的,其所有的调度规则都是依据于WorkflowRunner 类的run 方法。采用遍历循环的方式,这个遍历机制就是:
/***** 摘自WorkflowRunner 类的run 方法****/
while (!_activityStack.isEmpty()) {
//_activityStack 中暂存着需要被激活的活动实例
ActivityContext ap = (ActivityContext)_activityStack.pop();
_ctx.setActivityContext(ap.activity, ap.instance);
//虽然叫execute,但是其实际上是一个激活活动实例的行为executeActivityInstance(ap.activity, ap.instance);
}
/*在初始化任何一个活动实例后,将这个活动实例放入_activityStack 这个堆栈中。然后调用WorkflowRunner 的run 方法。在这个方法中,遍历_activityStack 堆栈中的活动实例,进行运行。*/
但是什么情况下会激活WorkflowRunner 的run 呢?StartProcess,startActivity,completeActivity,executeTransition 这些情况下,都会造成run 的运行。OBE 的调度算法是很简单,但是执行这个调度过程,是比较绕的。想弄清楚到底如何运行的,大家有必要去仔细阅读阅读WorkflowRunner 类。从StartProcess 方法开始,跟踪起startActivity,completeActivity,executeTransition 这几个方法之间的调用关系。这样的引擎调度机制是比较单一的。将一些控制判断交给了外围的过程。引擎本身并没有多少实际的调度,只是一个执行体:获取需要执行(激活)的活动实例,然后执行(激活)。
工作流引擎核心调度算法与PetriNet by 胡长城(银狐999)补充一下,OBE 有个非常值得参考和吸收的地方,就是其Listener 的应用。虽然Listener对引擎来说只是一个外设,但是却为其跟踪整个引擎得调度留下了很多可扩展接口。当然OBE 内核主要是两个类:WorkflowRunner(负责引擎调度)和EngineContext (运行环境)。
Shark 的引擎调度机制
和OBE 同样支持XPDL 的模型描绘语言的还有一个引擎Shark,Shark 是目前体系结构最为庞大和完善的开源工作流引擎。不光提供了对分布式的支持(基于Corba),而且提供了多线程的事务安全控制。
Shark 的内部调度机制也比较简单,与OBE 类似。Shark 的整个调度方法也基本上是基于WfProcessImpl 内的run 方法,也采用的是遍历循环的方式。只是OBE 是遍历待激活的活动实例,而Shark 是遍历已经完成的活动实例,然后往下推进。——估计Shark 是故意为了避免。与OBE 类似,所以选择了这么一种算法。因为你会发现,他们的执行推进机制是较为相像的。
Shark 遍历循环的机制是:
/***** 摘自WfProcessImpl 类的run 方法****/
protected void run (SharkTransaction t, WfActivityInternal lastFinishedActivity){
//如说是启动流程,启动流程实例的时候,不指定lastFinishedActivity
if (lastFinishedActivity==null) {
Set starts=getProcessDefinition(t).getStartingActivities();
for (Iterator it=starts.iterator(); it.hasNext();) {
startActivity(t,asDefId,actDef,null);
}
}
//开始遍历已经结束的活动实例
while (lastFinishedActivities.size()>0) {
if
(!state.equals(SharkConstants.STATE_OPEN_NOT_RUNNING_SUSPENDE D)) {
//执行当前活动实例后续的行为
queueNext(t, (WfActivityInternal)lastFinishedActivities.get(0));
lastFinishedActivities.remove(0);
} else {
return;
}
}
}
/*任何一个活动点完成之后(不论是Complete 还是Terminate),会将自身放入lastFinishedActivities 列表中,然后调用run 方法,促发对这个列表的循环遍历。*/
有兴趣对这方面研究的,可以看看WfProcessImpl 内的start、run、
activity_complete、activity_terminate 这几个方法。
工作流引擎核心调度算法与PetriNet by 胡长城(银狐999)
从调度机制上说,shark 和obe 基本雷同。甚至可以看到,其两个运行类都基本上有些类似:shark 是WfProcessImpl 类,obe 是WorkflowRunner 类。两个类都是即包含了调度的前推因素(比如起动流程实例、活动实例结束等方法),也包含了调度的规则运算(run 方法)。唯一不同的就是,shark 是对已经完成的活动实例进行遍历,然后前推;而OBE 则是对需要激活的活动实例进行遍历,进行前推。
点评:
OBE 和Shark 的run 调度方法,是比较常用的调度机制。首先效率上比较还是可以,其实比较直观,也容易理解。而且连个引擎的执行机制有一定的雷同,这可能是由于两者都采用XPDL 的缘故。
但是,受他们调度机制的影响。OBE 和Shark 是很难支持复杂的运转模型,比如“抢占模式(Workflow Pattern 中叫延迟选择)”。