您可以在Camunda BPM上写死锁吗?我可以

图片


前一段时间,我写了一篇关于从IBM BPM到Camunda的成功迁移的文章,现在我们的生活充满了幸福和愉悦的印象。Camunda并没有让我们失望,我们继续与BPM引擎保持友谊。



但是,可惜的是,卡蒙达还可能会带来令人不快的惊喜,因此有时无法获得最明显的结果。在本文中,将考虑一个案例,尽管它很简单,但事实却比乍看之下有趣且复杂得多。



我们训练猫



为了描述问题,请考虑一个综合示例。假设我们决定扩大客户群,并且需要为猫和猫服务。应该检查每个潜在客户,并可能立即提供一些东西。



我们将检查候选人的可靠性以及我们可以为他提供的服务。尽职调查和可能的服务没有任何关系-这些动作可以并行执行。在bpmn图上以示意图形式显示,如下所示:





图1.毛发服务的示意图过程



该图示意性地显示了基本步骤,派生和加入网关。





此图标描述了并行网关。并行网关是用于构建流程的并行运行部分的最简单网关。



并行网关有两种类型:



  • fork-为每个分支创建一个单独的执行;
  • join-等待所有传入执行完成。


执行 -表示流程实例中的“执行路径”(来自文档)。也就是说,它是流程执行的线程。



现在,让任务复杂一些。我们将按照以下方式检查和搜索服务:首先,我们检查客户端的状态,然后查看适合他的服务,然后进行一些预处理。另外,几种服务可能一次适合客户,因此我们应该能够将所有服务提供给客户。



由于我们与毛茸茸的客户合作,因此服务将是适当的:缬草,爪耙,主人的枕头和其他有用的物品。





图2.更新的蓬松客户服务图



该过程新版本如下。该过程将并行进行可靠性检查和搜索可能的建议。搜索也并行化。在这种情况下,将执行满足相应条件的那些分支。



为了与条件并行化,将使用包含网关,该网关由以下图标指示:





包含网关是具有分支条件的并行网关。条件成立的分支将被执行。



网关有两种类型:



  • fork-为每个满足条件的分支创建执行,并以与并行网关中执行相同的方式并行执行;
  • join与Parallel Gateway不同,它不等待所有分支的执行,而是等待条件为真的分支的执行。


可能发生的情况是执行的检查不足,因此必须再次检查客户端。为此,请在所有检查的末尾添加一个条件,然后将其发送以重新检查,直到最开始:





图3.应该起作用的过程的最终版本







什么?发生了什么?



在这里,奇怪的事情开始发生。可靠性检查分支工作并到达收集并行网关。到目前为止,一切都很好。



第二分支检查物料条件,并根据结果执行相应的任务。此外,该过程在收集包容性网关的网关处停止,并且不再继续。如果您查看Coockpit(Kamunda的管理面板),那么执行将挂在收集的Inclusive Gateway和Parallel Gateway上。





图4.悬挂式维护过程



可以说,卡蒙达的进程陷入了僵局。在这种情况下,它与并行编程和死锁理论中的死锁没有直接关系。



寻找̶̶r̶i̶k̶l̶uch̶e̶n̶i̶y̶答案



由于我对发生的事情以及为什么停止过程没有足够的了解,因此我不得不凭经验解决问题。



也许您需要Inclusive Gateway的默认分支,没有它,进程将无法正常运行?



当然很奇怪,但是尝试添加默认分支。默认分支的存在是一种很好的做法,因为否则可能无法满足单个条件,那么我们将得到一个错误。





图5.使用默认分支的服务流程



启动并获得相同的结果-该流程仍然挂在Inclusive Gateway上。



接下来是各种参数的枚举,请阅读文档,这将持续半天。在另一尝试中,该过程意外地通过了失败的任务。在搜索和调试过程中,上层分支通过客户端可靠性检查被删除的情况下,包含Inclusive Gateway的下层分支工作。也就是说,当进程仅使用Inclusive Gateway退化到较低的分支时,进程结束。





图6.退化过程



事实证明,并行网关以某种方式影响了包容性网关。这很奇怪,不合逻辑,不应该。



这怎么可能?也许您应该重新阅读有关并行和包容网关如何工作的理论。加入网关聚集所有人并继续进行该流程应该怎么办?在Internet上,他们写道,每个收集的“包含网关”(联接)都等待与进入“叉子”的号码相同的号码进入。然后突然出现了另一个问题:这个计数器到底如何工作?



你是做什么的?你如何工作的?



这个问题值得拼图游戏和智能电视节目。只有在电视节目中,他们才可以打电话给朋友。另一方面,我也可以寻求帮助。我们将称呼我们的业务流程设计师Denis。



-丹尼斯,你好!您能告诉我收集方式如何确定何时该继续进行吗?他们到处写道:“有多少钱-应该有很多钱进来。”但是他怎么认为呢?

- 很简单。 Camunda计算活动执行的次数。

- 非常感谢。现在,




考虑发生了什么。为此,再次调用初始方案,结果是:





图7.使用默认分支的挂起过程



为简单起见,我们考虑满足所有条件的情况。满足这些条件后的三个任务时,我们会有什么?



有多少活动执行?较低的三个分支,较高的一个分支,我们检查了客户的可靠性。Camunda不在乎这些是完全不同的并行分支。仅关注活动执行的数量,其中有四个,而传入的包含网关仅接收三个。



我们纠正



为了纠正这种情况,收集网关必须立即收集所有执行,然后从理论上讲,该过程将继续进行。让我们尝试保留一个而不是两个联接网关:





图8.流程的更正版本



在我看来,编辑该流程之后,看上去就不太明显了。但是它最初按计划工作。至此,任务安全地结束了,我得以推动更改并回家。



乐趣才刚刚开始



当我坐下来写这篇文章并拿出一个可以描述这种情况的流程示例时,我很失望:该流程按预期进行,没有死锁。



首先,我假设示例中的Camunda版本高于项目中的版本,而在新版本中,此问题已得到解决。但是降级Camunda却无济于事。顺便说一句,在所有示例中,都使用版本7.8.0-它与最新版本相去甚远,但这并不重要。还检查了该问题,并在当前最新版本7.13上进行了复制。



通过反复试验,问题得以解决。原始的伪造示例没有反向分支,这与我在工作场所中开发的过程不同。



事实证明,在存在反向分支的情况下,问题得以重现,并且我们陷入了一种僵局,没有反向分支,一切都会按预期进行。



案例需要理解和分析。为此,我必须查看Camunda BPM源代码。由于问题是Inclusive Gateway所致,因此在负责该元素-InclusiveGatewayActivityBehavior行为的类中寻找答案似乎是合乎逻辑的在该过程的两个版本上运行几次调试,我意识到它是如何工作的。



如果不清楚,请参阅资源!



为了不使故事变得晦涩,基于源代码对InclusiveGateway的工作进行描述是粗略的。我们感兴趣的逻辑集中在execute方法上,在这种情况下,activatesGateway方法是最有价值的。据我了解,它检查是否可以通过InclusiveGateway。每次执行(正在运行的每个分支)都会调用execute方法。在我们的例子中,有三个这样的分支,这意味着该方法将被调用三次。



让我们看看activatesGateway方法是如何工作的。为了更好地理解,让我们为所有可执行分支命名。





图9.带有执行的流程图



根据我的理解,该方法的逻辑如下:比较到达该高速公路的处决次数和该高速公路包括的箭的数量。这种检查是在最简单的情况下执行的,当所有的Inclusive Gateway分支都被执行时,检查收集网关的逻辑是等待直到输入的执行次数等于传入的箭头数。也就是说,在最简单的情况下,执行方法的调用次数与收集网关中存在分支的次数相同,然后该过程继续进行。



在我们的例子中,此方法被调用了3次,因为传入执行的次数将从1增加到3。在最后一次调用时,传入执行的次数和传出执行的次数分别为3和4,并且我们将遵循false分支。



如果不满足条件,则检查其余执行是否属于“包含网关”。即,检查活动执行到达联接包含网关的能力。



在这里,您需要一点耐心,呼气和阅读。结局就在附近!



在activatesGateway方法的false分支中,在每次调用时,将检查尚未到达包含联接执行的那些调用,以检查达到此联接的可能性。如果至少有一次执行可以导致Inclusive Gateway,则您需要将其考虑在内,并等待其加入此联接。如果没有可以导致加入的执行,则该方法将返回true。



最有趣的部分即将到来。乍一看,最后的执行(在图中-执行1)不能导致包含网关。但是,值得一看的是参与该验证canReachActivity方法的实现,并且此元素的这种行为的原因将变得清楚。



如果我们丢弃了所有代码细节,则在该方法内部递归调用isReachable方法,该方法逐步检查此执行是否进入收集的InclusiveGateway中。反向分支只是提供了这样的机会,可惜,尽管没有,但是应该考虑到这一点,因为我们将在所有联接之后返回。



结果,Inclusive Gateway正在等待另一个执行,它将永远不会发生。因此,我们陷入了僵局。原则上,如果放弃这些约定,则会遇到经典的死锁:在Parallel上加入join等待包含Inclusive的分支被执行,相反,在Inclusive包含Branch的分支等待Parallel执行。



下图显示了从执行开始检查Inclusive Gateway联接可用性的大致方向,该联接是通过并行分支加入Prallel Gateway的。





图10.从并行联接到包含联接



可能路径该图显示,实际上,从并行网关联接开始,可以使用联接包含网关,并且根据Camunda BPM逻辑,有没有“圈内领先”。



在找出原因之后,不经意间出现了一个问题:这是错误还是功能?我认为这是一个错误。现在,我正在收集信息和案例,以将报告发送给Camunda团队。



问题是本地化的,这很好。但是现在呢?



实际上,现在-结论:



  1. 有备则无患。我们需要考虑到Camunda的这种行为来构建我们的流程。
  2. , . parallel join.
  3. Inclusive Gateway , , executions .
  4. , . , Parallel Gateway .


明显的简单性和清晰度有时会引起误解。这只能通过知识的积累和复制来解决。las,在解决这个问题时,我对Inclusive Join的逻辑并不了解,所以我不得不动手。我通过反复试验,打电话给朋友和调试源获得了这些知识。



从这一切可以得出一个显而易见的,远非新结论,那就是您需要了解所使用工具的工作方式。您了解得越多,此类问题就会越少。



第二个结论也很明显:您不仅需要分解代码,还需要分解过程。



在解析这种情况和撰写文章时有用的链接:



  1. 资料来源Camunda BPM
  2. 包含网关的职位描述
  3. 并行网关如何工作



All Articles