protected void handleMultiInstance()

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);

        }
    }