Flowable源码地址:https://github.com/flowable/flowable-engine
Flowable-6.7.2 源码注释地址:https://github.com/solojin/flowable-6.7.2-annotated
包路径:org.flowable.engine.impl.jobexecutor
ParallelMultiInstanceWithNoWaitStatesAsyncLeaveJobHandler 无等待状态的并行多实例异步离开作业处理器
/**
* 无等待状态的并行多实例异步离开作业处理器
*
* @author Joram Barrez
*/
public class ParallelMultiInstanceWithNoWaitStatesAsyncLeaveJobHandler implements JobHandler {
public static final String TYPE = "parallel-multi-instance-no-waits-async-leave";
@Override
public String getType() {
return TYPE;
}
@Override
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
ExecutionEntityManager executionEntityManager = processEngineConfiguration.getExecutionEntityManager();
ExecutionEntity execution = executionEntityManager.findById(job.getExecutionId());
if (execution != null) {
FlowElement currentFlowElement = execution.getCurrentFlowElement();
if (currentFlowElement instanceof Activity) {
Object behavior = ((Activity) currentFlowElement).getBehavior();
if (behavior instanceof ParallelMultiInstanceBehavior) {
ParallelMultiInstanceBehavior parallelMultiInstanceBehavior = (ParallelMultiInstanceBehavior) behavior;
DelegateExecution multiInstanceRootExecution = ExecutionGraphUtil.getMultiInstanceRootExecution(execution);
if (multiInstanceRootExecution != null) {
// 优化此处的活动计数:如果数据库中仍有活动执行,则无需执行任何操作:
// 无需获取任何变量,如已完成的、活动的nr等。
// 这项工作可以简单地被重新安排,并且在事情尚未完成时,它将再次尝试相同的逻辑。
long activeChildExecutionCount = executionEntityManager.countActiveExecutionsByParentId(multiInstanceRootExecution.getId());
if (activeChildExecutionCount > 0) {
List<String> boundaryEventActivityIds = ExecutionGraphUtil.getBoundaryEventActivityIds(multiInstanceRootExecution);
if (boundaryEventActivityIds.isEmpty()) {
reCreateJob(processEngineConfiguration, execution);
} else {
// 如果所有剩余的执行都是边界事件执行,则可以保留多实例。
List<ExecutionEntity> boundaryEventChildExecutions = executionEntityManager
.findExecutionsByParentExecutionAndActivityIds(multiInstanceRootExecution.getId(), boundaryEventActivityIds);
if (activeChildExecutionCount <= boundaryEventChildExecutions.size()) {
leaveMultiInstance(processEngineConfiguration, execution, parallelMultiInstanceBehavior);
} else {
reCreateJob(processEngineConfiguration, execution);
}
}
} else {
leaveMultiInstance(processEngineConfiguration, execution, parallelMultiInstanceBehavior);
}
}
}
}
}
}
protected void reCreateJob(ProcessEngineConfigurationImpl processEngineConfiguration, ExecutionEntity execution) {
// 这不是创建作业的常见方式,因为我们特别不希望异步执行器触发。
// 该作业应在下一个采集周期中提取,以避免连续循环。
JobService jobService = processEngineConfiguration.getJobServiceConfiguration().getJobService();
JobEntity newJob = JobUtil.createJob(execution, TYPE, processEngineConfiguration);
jobService.createAsyncJobNoTriggerAsyncExecutor(newJob, true);
jobService.insertJob(newJob);
}
protected void leaveMultiInstance(ProcessEngineConfigurationImpl processEngineConfiguration, ExecutionEntity execution,
ParallelMultiInstanceBehavior parallelMultiInstanceBehavior) {
// ParallelMultiInstanceBehavior的实现考虑了子执行。
// 因此选择随机子执行而不是传递多实例根执行
boolean multiInstanceCompleted = parallelMultiInstanceBehavior.leaveAsync(execution);
if (!multiInstanceCompleted) {
reCreateJob(processEngineConfiguration, execution);
}
}
}
ParallelMultiInstanceActivityCompletionJobHandler 并行多实例活动完成作业处理器
/**
* 并行多实例活动完成作业处理器
*
* @author Filip Hrisafov
*/
public class ParallelMultiInstanceActivityCompletionJobHandler implements JobHandler {
public static final String TYPE = "parallel-multi-instance-complete";
@Override
public String getType() {
return TYPE;
}
@Override
public void execute(JobEntity job, String configuration, VariableScope variableScope, CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
ExecutionEntity completingExecution = processEngineConfiguration.getExecutionEntityManager().findById(job.getExecutionId());
if (completingExecution != null) {
// It is possible that the execution completed (through another thread). In that case we ignore it.
FlowElement currentFlowElement = completingExecution.getCurrentFlowElement();
if (currentFlowElement instanceof Activity) {
Object behavior = ((Activity) currentFlowElement).getBehavior();
if (behavior instanceof ParallelMultiInstanceBehavior) {
ParallelMultiInstanceBehavior parallelMultiInstanceBehavior = (ParallelMultiInstanceBehavior) behavior;
parallelMultiInstanceBehavior.leaveAsync(completingExecution);
}
}
}
}
}