flowable源码解读——并行多实例节点任务是否是顺序生成

本文主要是介绍flowable源码解读——并行多实例节点任务是否是顺序生成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 最近在项目开发中需要在多实例开始监听里修改一个全局的计数变量,不太确定并行多实例任务在底层引擎是顺序生成还是并行生成的,如果是顺序生成的则不影响,如果是并行生成 则修改一个全局的计数变量就会出现数据错误问题,查阅了flowable源码,做个记录。

查看并行多实例节点任务类 ParallelMultiInstanceBehavior,代码如下:
    protected int createInstances(DelegateExecution multiInstanceRootExecution) {int nrOfInstances = resolveNrOfInstances(multiInstanceRootExecution);if (nrOfInstances < 0) {throw new FlowableIllegalArgumentException("Invalid number of instances: must be non-negative integer value" + ", but was " + nrOfInstances);}setLoopVariable(multiInstanceRootExecution, NUMBER_OF_INSTANCES, nrOfInstances);setLoopVariable(multiInstanceRootExecution, NUMBER_OF_COMPLETED_INSTANCES, 0);setLoopVariable(multiInstanceRootExecution, NUMBER_OF_ACTIVE_INSTANCES, nrOfInstances);List<ExecutionEntity> concurrentExecutions = new ArrayList<>();for (int loopCounter = 0; loopCounter < nrOfInstances; loopCounter++) {ExecutionEntity concurrentExecution = CommandContextUtil.getExecutionEntityManager().createChildExecution((ExecutionEntity) multiInstanceRootExecution);concurrentExecution.setCurrentFlowElement(activity);concurrentExecution.setActive(true);concurrentExecution.setScope(false);concurrentExecutions.add(concurrentExecution);logLoopDetails(concurrentExecution, "initialized", loopCounter, 0, nrOfInstances, nrOfInstances);//CommandContextUtil.getHistoryManager().recordActivityStart(concurrentExecution);}// Before the activities are executed, all executions MUST be created up front// Do not try to merge this loop with the previous one, as it will lead// to bugs, due to possible child execution pruning.for (int loopCounter = 0; loopCounter < nrOfInstances; loopCounter++) {ExecutionEntity concurrentExecution = concurrentExecutions.get(loopCounter);// executions can be inactive, if instances are all automatics// (no-waitstate) and completionCondition has been met in the meantimeif (concurrentExecution.isActive() && !concurrentExecution.isEnded() && !concurrentExecution.getParent().isEnded()) {executeOriginalBehavior(concurrentExecution, (ExecutionEntity) multiInstanceRootExecution, loopCounter);} }// See ACT-1586: ExecutionQuery returns wrong results when using multi// instance on a receive task The parent execution must be set to false, so it wouldn't show up in// the execution query when using .activityId(something). Do not we cannot nullify the// activityId (that would have been a better solution), as it would break boundary event behavior.if (!concurrentExecutions.isEmpty()) {multiInstanceRootExecution.setActive(false);}return nrOfInstances;}

通过源码可以看出,并行多实例任务底层还是按顺序生成的,并不是并行生成。

以下是 该类的结构图:

 可以看出该类是继承 FlowNodeActivityBehavior 类,以下是FlowNodeActivityBehavior的源码:

/* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at* *      http://www.apache.org/licenses/LICENSE-2.0* * Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
package org.flowable.engine.impl.bpmn.behavior;import org.flowable.bpmn.model.FlowNode;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.impl.delegate.TriggerableActivityBehavior;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;/*** Superclass for all 'connectable' BPMN 2.0 process elements: tasks, gateways and events. This means that any subclass can be the source or target of a sequenceflow.* * Corresponds with the notion of the 'flownode' in BPMN 2.0.* * @author Joram Barrez*/
public abstract class FlowNodeActivityBehavior implements TriggerableActivityBehavior {private static final long serialVersionUID = 1L;protected BpmnActivityBehavior bpmnActivityBehavior = new BpmnActivityBehavior();/*** Default behaviour: just leave the activity with no extra functionality.*/@Overridepublic void execute(DelegateExecution execution) {leave(execution);}/*** Default way of leaving a BPMN 2.0 activity: evaluate the conditions on the outgoing sequence flow and take those that evaluate to true.*/public void leave(DelegateExecution execution) {bpmnActivityBehavior.performDefaultOutgoingBehavior((ExecutionEntity) execution);}public void leaveIgnoreConditions(DelegateExecution execution) {bpmnActivityBehavior.performIgnoreConditionsOutgoingBehavior((ExecutionEntity) execution);}@Overridepublic void trigger(DelegateExecution execution, String signalName, Object signalData) {// concrete activity behaviours that do accept signals should override this method;throw new FlowableException("this activity isn't waiting for a trigger");}protected String parseActivityType(FlowNode flowNode) {String elementType = flowNode.getClass().getSimpleName();elementType = elementType.substring(0, 1).toLowerCase() + elementType.substring(1);return elementType;}
}
FlowNodeActivityBehavior是流节点活动行为类,是所有“可连接”BPMN 2.0流程元素的超类:任务、网关和事件。这意味着任何子类都可以是sequenceflow的源或目标。与BPMN 2.0中的“流节点”(flownode)概念相对应。

FlowNodeActivityBehavior 的职责和作用

  1. 定义流程节点的行为:

    • FlowNodeActivityBehavior接口定义了处理流程节点的标准行为,例如开始、结束、分支等。
    • 实现这个接口的类负责处理特定类型的流程节点,比如服务任务、用户任务、网关等。
  2. 执行流程节点的逻辑:

    • 当流程执行器到达某个流程节点时,它会查找该节点的行为实现,并调用相应的方法来执行节点的逻辑。
    • 这些方法包括但不限于executeleave等,它们负责处理节点的进入、执行和离开等操作。
  3. 支持不同类型的流程节点:

    • 不同类型的流程节点会有不同的行为实现,例如用户任务和服务任务会有各自的实现类。
    • 例如,用户任务的行为实现类可能需要处理用户界面交互,而服务任务的行为实现类则可能需要调用外部系统的服务。

关键方法

FlowNodeActivityBehavior接口包含以下方法:

  • execute(Execution execution): 负责执行流程节点的主要逻辑。当流程执行器到达该节点时,会调用此方法。
  • leave(Execution execution): 负责在流程节点执行完成后离开该节点的操作。这通常涉及到更新执行状态、触发后续路径等。

这篇关于flowable源码解读——并行多实例节点任务是否是顺序生成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1098834

相关文章

使用python生成固定格式序号的方法详解

《使用python生成固定格式序号的方法详解》这篇文章主要为大家详细介绍了如何使用python生成固定格式序号,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录生成结果验证完整生成代码扩展说明1. 保存到文本文件2. 转换为jsON格式3. 处理特殊序号格式(如带圈数字)4

Java使用Swing生成一个最大公约数计算器

《Java使用Swing生成一个最大公约数计算器》这篇文章主要为大家详细介绍了Java使用Swing生成一个最大公约数计算器的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下... 目录第一步:利用欧几里得算法计算最大公约数欧几里得算法的证明情形 1:b=0情形 2:b>0完成相关代码第二步:加

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

MySQL之搜索引擎使用解读

《MySQL之搜索引擎使用解读》MySQL存储引擎是数据存储和管理的核心组件,不同引擎(如InnoDB、MyISAM)采用不同机制,InnoDB支持事务与行锁,适合高并发场景;MyISAM不支持事务,... 目录mysql的存储引擎是什么MySQL存储引擎的功能MySQL的存储引擎的分类查看存储引擎1.命令

Spring的基础事务注解@Transactional作用解读

《Spring的基础事务注解@Transactional作用解读》文章介绍了Spring框架中的事务管理,核心注解@Transactional用于声明事务,支持传播机制、隔离级别等配置,结合@Tran... 目录一、事务管理基础1.1 Spring事务的核心注解1.2 注解属性详解1.3 实现原理二、事务事

k8s admin用户生成token方式

《k8sadmin用户生成token方式》用户使用Kubernetes1.28创建admin命名空间并部署,通过ClusterRoleBinding为jenkins用户授权集群级权限,生成并获取其t... 目录k8s admin用户生成token创建一个admin的命名空间查看k8s namespace 的

PyQt6 键盘事件处理的实现及实例代码

《PyQt6键盘事件处理的实现及实例代码》本文主要介绍了PyQt6键盘事件处理的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起... 目录一、键盘事件处理详解1、核心事件处理器2、事件对象 QKeyEvent3、修饰键处理(1)、修饰键类

Linux五种IO模型的使用解读

《Linux五种IO模型的使用解读》文章系统解析了Linux的五种IO模型(阻塞、非阻塞、IO复用、信号驱动、异步),重点区分同步与异步IO的本质差异,强调同步由用户发起,异步由内核触发,通过对比各模... 目录1.IO模型简介2.五种IO模型2.1 IO模型分析方法2.2 阻塞IO2.3 非阻塞IO2.4

Spring定时任务之fixedRateString的实现示例

《Spring定时任务之fixedRateString的实现示例》本文主要介绍了Spring定时任务之fixedRateString的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录从毫秒到 Duration:为何要改变?核心:Java.time.Duration.parse

Oracle Scheduler任务故障诊断方法实战指南

《OracleScheduler任务故障诊断方法实战指南》Oracle数据库作为企业级应用中最常用的关系型数据库管理系统之一,偶尔会遇到各种故障和问题,:本文主要介绍OracleSchedul... 目录前言一、故障场景:当定时任务突然“消失”二、基础环境诊断:搭建“全局视角”1. 数据库实例与PDB状态2