Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        protected override void RunOperation()
        {
            try
            {
                // Find the actual scope that needs to be destroyed.
                // This could be the incoming execution, or the first parent execution where isScope = true

                // Find parent scope execution
                IExecutionEntity scopeExecution = execution.IsScope ? execution : FindFirstParentScopeExecution(execution);

                if (scopeExecution == null)
                {
                    throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event");
                }

                IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;
                DeleteAllChildExecutions(executionEntityManager, scopeExecution);

                // Delete all scope tasks
                ITaskEntityManager taskEntityManager = commandContext.TaskEntityManager;
                DeleteAllScopeTasks(scopeExecution, taskEntityManager);

                // Delete all scope jobs
                ITimerJobEntityManager timerJobEntityManager = commandContext.TimerJobEntityManager;
                DeleteAllScopeJobs(scopeExecution, timerJobEntityManager);

                // Remove variables associated with this scope
                IVariableInstanceEntityManager variableInstanceEntityManager = commandContext.VariableInstanceEntityManager;
                RemoveAllVariablesFromScope(scopeExecution, variableInstanceEntityManager);

                commandContext.HistoryManager.RecordActivityEnd(scopeExecution, scopeExecution.DeleteReason);
                executionEntityManager.Delete(scopeExecution);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, ex.Message);
                throw;
            }
        }
Ejemplo n.º 2
0
        public override void Execute(IExecutionEntity execution)
        {
            ICommandContext         commandContext         = Context.CommandContext;
            IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager;

            // find cancel boundary event:
            IExecutionEntity parentScopeExecution       = null;
            IExecutionEntity currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(execution.ParentId);

            while (currentlyExaminedExecution != null && parentScopeExecution == null)
            {
                if (currentlyExaminedExecution.CurrentFlowElement is SubProcess)
                {
                    parentScopeExecution = currentlyExaminedExecution;
                    SubProcess subProcess = (SubProcess)currentlyExaminedExecution.CurrentFlowElement;
                    if (subProcess.LoopCharacteristics != null)
                    {
                        IExecutionEntity miExecution = parentScopeExecution.Parent;
                        FlowElement      miElement   = miExecution.CurrentFlowElement;
                        if (miElement != null && miElement.Id.Equals(subProcess.Id))
                        {
                            parentScopeExecution = miExecution;
                        }
                    }
                }
                else
                {
                    currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                }
            }

            if (parentScopeExecution == null)
            {
                throw new ActivitiException("No sub process execution found for cancel end event " + execution.CurrentActivityId);
            }

            {
                SubProcess    subProcess          = (SubProcess)parentScopeExecution.CurrentFlowElement;
                BoundaryEvent cancelBoundaryEvent = null;
                if (CollectionUtil.IsNotEmpty(subProcess.BoundaryEvents))
                {
                    foreach (BoundaryEvent boundaryEvent in subProcess.BoundaryEvents)
                    {
                        if (CollectionUtil.IsNotEmpty(boundaryEvent.EventDefinitions) && boundaryEvent.EventDefinitions[0] is CancelEventDefinition)
                        {
                            cancelBoundaryEvent = boundaryEvent;
                            break;
                        }
                    }
                }

                if (cancelBoundaryEvent == null)
                {
                    throw new ActivitiException("Could not find cancel boundary event for cancel end event " + execution.CurrentActivityId);
                }

                IExecutionEntity newParentScopeExecution = null;
                currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(parentScopeExecution.ParentId);
                while (currentlyExaminedExecution != null && newParentScopeExecution == null)
                {
                    if (currentlyExaminedExecution.IsScope)
                    {
                        newParentScopeExecution = currentlyExaminedExecution;
                    }
                    else
                    {
                        currentlyExaminedExecution = executionEntityManager.FindById <IExecutionEntity>(currentlyExaminedExecution.ParentId);
                    }
                }

                ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(parentScopeExecution);

                if (subProcess.LoopCharacteristics != null)
                {
                    IList <IExecutionEntity> multiInstanceExecutions = parentScopeExecution.Executions;
                    IList <IExecutionEntity> executionsToDelete      = new List <IExecutionEntity>();
                    foreach (IExecutionEntity multiInstanceExecution in multiInstanceExecutions)
                    {
                        if (!multiInstanceExecution.Id.Equals(parentScopeExecution.Id))
                        {
                            ScopeUtil.CreateCopyOfSubProcessExecutionForCompensation(multiInstanceExecution);

                            // end all executions in the scope of the transaction
                            executionsToDelete.Add(multiInstanceExecution);
                            DeleteChildExecutions(multiInstanceExecution, execution, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                        }
                    }

                    foreach (IExecutionEntity executionEntityToDelete in executionsToDelete)
                    {
                        DeleteChildExecutions(executionEntityToDelete, execution, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                    }
                }

                // The current activity is finished (and will not be ended in the deleteChildExecutions)
                commandContext.HistoryManager.RecordActivityEnd(execution, null);

                // TODO: 先删除已生成的边界取消执行实例
                var cancelBoundaryEventExecution = executionEntityManager.FindExecutionsByParentExecutionAndActivityIds(parentScopeExecution.Id, new string[] { cancelBoundaryEvent.Id }).FirstOrDefault();
                executionEntityManager.Delete(cancelBoundaryEventExecution);

                // set new parent for boundary event execution
                execution.Parent             = newParentScopeExecution ?? throw new ActivitiException("Programmatic error: no parent scope execution found for boundary event " + cancelBoundaryEvent.Id);
                execution.CurrentFlowElement = cancelBoundaryEvent;

                // end all executions in the scope of the transaction
                DeleteChildExecutions(parentScopeExecution, execution, commandContext, History.DeleteReasonFields.TRANSACTION_CANCELED);
                commandContext.HistoryManager.RecordActivityEnd(parentScopeExecution, History.DeleteReasonFields.TRANSACTION_CANCELED);

                Context.Agenda.PlanTriggerExecutionOperation(execution);
            }
        }