in core/src/main/java/com/alibaba/smart/framework/engine/behavior/impl/UserTaskBehavior.java [170:287]
protected void handleMultiInstance(ExecutionContext context, ExecutionInstance executionInstance, UserTask userTask,
MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics) {
ActivityInstance activityInstance = context.getActivityInstance();
SmartEngine smartEngine = processEngineConfiguration.getSmartEngine();
//重要前提: 在会签场景中,ei:ti:tai= 1:1:1 ,并且会签场景中, assigneeType 应该只能为 user.
//1. 当前的数据库中所有的 totalExecutionInstanceList,包含所有状态的。 但是此时,由于顺序会签的问题,totalExecutionInstanceList 不再是所有的ExecutionList了。
List<ExecutionInstance> totalExecutionInstanceList = executionInstanceStorage.findByActivityInstanceId(
activityInstance.getProcessInstanceId(), activityInstance.getInstanceId(),
this.processEngineConfiguration);
// 针对顺序会签,这里totalInstanceCount 为目前已经创建出来的count,未来还会补偿新增; 但是针对非顺序会签,则是最终的全量,不会再变.
Integer totalInstanceCount = totalExecutionInstanceList.size();
Integer passedTaskInstanceCount = 0;
Integer rejectedTaskInstanceCount = 0;
MultiInstanceCounter multiInstanceCounter = context.getProcessEngineConfiguration().getMultiInstanceCounter();
if(multiInstanceCounter != null) {
passedTaskInstanceCount = multiInstanceCounter.countPassedTaskInstanceNumber(
activityInstance.getProcessInstanceId(), activityInstance.getInstanceId(), smartEngine);
rejectedTaskInstanceCount = multiInstanceCounter.countRejectedTaskInstanceNumber(
activityInstance.getProcessInstanceId(), activityInstance.getInstanceId(), smartEngine);
} else {
throw new ValidationException("MultiInstanceCounter can NOT be null for multiInstanceLoopCharacteristics");
}
// 不变式 nrOfCompletedInstances + nrOfRejectedInstance <= nrOfInstances
Map<String,Object> requestContext = new HashMap<String, Object>(4);
requestContext.put("nrOfCompletedInstances", passedTaskInstanceCount);
requestContext.put("nrOfRejectedInstance", rejectedTaskInstanceCount);
requestContext.put("nrOfInstances", totalInstanceCount);
// 注意:任务处理的并发性,需要业务程序来控制。
boolean abortMatched = false;
ConditionExpression abortCondition = multiInstanceLoopCharacteristics.getAbortCondition();
if (null != abortCondition) {
abortMatched = ExpressionUtil.eval(requestContext, abortCondition,context.getProcessEngineConfiguration());
}
//此时,尚未触发订单abort逻辑
if (!abortMatched) {
ConditionExpression completionCondition = multiInstanceLoopCharacteristics.getCompletionCondition();
if(null != completionCondition){
boolean passedMatched = ExpressionUtil.eval(requestContext, completionCondition,context.getProcessEngineConfiguration()) ;
Integer completedTaskInstanceCount = passedTaskInstanceCount + rejectedTaskInstanceCount;
if(completedTaskInstanceCount < totalInstanceCount){
if(passedMatched){
UserTaskBehaviorHelper.markDoneEIAndCancelTI(context, executionInstance, totalExecutionInstanceList,executionInstanceStorage,processEngineConfiguration);
context.setNeedPause(false);
} else {
context.setNeedPause(true);
//生成顺序型会签,需要补偿创建任务。
if(multiInstanceLoopCharacteristics.isSequential()){
Map<String, TaskAssigneeCandidateInstance> taskAssigneeMap = queryTaskAssigneeCandidateInstance(context, userTask);
UserTaskBehaviorHelper.compensateExecutionAndTask(context, userTask, activityInstance, executionInstance, taskAssigneeMap,executionInstanceStorage,executionInstanceFactory,taskInstanceFactory,processEngineConfiguration);
}else{
// do nothing
}
}
}else if(completedTaskInstanceCount.equals(totalInstanceCount)){
if(passedMatched){
context.setNeedPause(false);
}else {
UserTaskBehaviorHelper.abortAndSetNeedPause(context, executionInstance, smartEngine);
}
}else{
handleException(totalInstanceCount, passedTaskInstanceCount, rejectedTaskInstanceCount);
}
}
else{
//completionCondition 为空时,则表示是all模式 (兼容历史逻辑), 则需要所有任务都完成后,才做判断。
if(rejectedTaskInstanceCount >= 1){
//fail fast ,abort
UserTaskBehaviorHelper.abortAndSetNeedPause(context, executionInstance, smartEngine);
UserTaskBehaviorHelper.markDoneEIAndCancelTI(context, executionInstance, totalExecutionInstanceList,executionInstanceStorage,processEngineConfiguration);
} else if(passedTaskInstanceCount < totalInstanceCount ){
context.setNeedPause(true);
if(multiInstanceLoopCharacteristics.isSequential()){
Map<String, TaskAssigneeCandidateInstance> taskAssigneeMap = queryTaskAssigneeCandidateInstance(context, userTask);
UserTaskBehaviorHelper.compensateExecutionAndTask(context, userTask, activityInstance, executionInstance, taskAssigneeMap,executionInstanceStorage,executionInstanceFactory,taskInstanceFactory,processEngineConfiguration);
} else {
//do nothing
}
}
else if(passedTaskInstanceCount.equals(totalInstanceCount) ){
context.setNeedPause(false);
}else{
handleException(totalInstanceCount, passedTaskInstanceCount, rejectedTaskInstanceCount);
}
}
} else {
UserTaskBehaviorHelper.abortAndSetNeedPause(context, executionInstance, smartEngine);
UserTaskBehaviorHelper.markDoneEIAndCancelTI(context, executionInstance, totalExecutionInstanceList,executionInstanceStorage,processEngineConfiguration);
}
}