public static void CreateCopyOfSubProcessExecutionForCompensation(IExecutionEntity subProcessExecution) { IEventSubscriptionEntityManager eventSubscriptionEntityManager = Context.CommandContext.EventSubscriptionEntityManager; IList <ICompensateEventSubscriptionEntity> compensateEventSubscriptions = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(subProcessExecution.Id); if (CollectionUtil.IsNotEmpty(compensateEventSubscriptions)) { IExecutionEntity processInstanceExecutionEntity = subProcessExecution.ProcessInstance; IExecutionEntity eventScopeExecution = Context.CommandContext.ExecutionEntityManager.CreateChildExecution(processInstanceExecutionEntity); eventScopeExecution.IsActive = false; eventScopeExecution.IsEventScope = true; eventScopeExecution.CurrentFlowElement = subProcessExecution.CurrentFlowElement; // copy local variables to eventScopeExecution by value. This way, // the eventScopeExecution references a 'snapshot' of the local variables (new SubProcessVariableSnapshotter()).SetVariablesSnapshots(subProcessExecution, eventScopeExecution); // set event subscriptions to the event scope execution: foreach (ICompensateEventSubscriptionEntity eventSubscriptionEntity in compensateEventSubscriptions) { eventSubscriptionEntityManager.Delete(eventSubscriptionEntity); ICompensateEventSubscriptionEntity newSubscription = eventSubscriptionEntityManager.InsertCompensationEvent(eventScopeExecution, eventSubscriptionEntity.ActivityId); newSubscription.Configuration = eventSubscriptionEntity.Configuration; newSubscription.Created = eventSubscriptionEntity.Created; } ICompensateEventSubscriptionEntity eventSubscription = eventSubscriptionEntityManager.InsertCompensationEvent(processInstanceExecutionEntity, eventScopeExecution.CurrentFlowElement.Id); eventSubscription.Configuration = eventScopeExecution.Id; } }
public override void Trigger(IExecutionEntity execution, string triggerName, object triggerData, bool throwError = true) { BoundaryEvent boundaryEvent = (BoundaryEvent)execution.CurrentFlowElement; ICommandContext commandContext = Context.CommandContext; IExecutionEntityManager executionEntityManager = commandContext.ExecutionEntityManager; IExecutionEntity subProcessExecution = null; // TODO: this can be optimized. A full search in the all executions shouldn't be needed IList <IExecutionEntity> processInstanceExecutions = executionEntityManager.FindChildExecutionsByProcessInstanceId(execution.ProcessInstanceId); foreach (IExecutionEntity childExecution in processInstanceExecutions) { if (childExecution.CurrentFlowElement != null && childExecution.CurrentFlowElement.Id.Equals(boundaryEvent.AttachedToRefId)) { subProcessExecution = childExecution; break; } } if (subProcessExecution == null) { throw new ActivitiException("No execution found for sub process of boundary cancel event " + boundaryEvent.Id); } IEventSubscriptionEntityManager eventSubscriptionEntityManager = commandContext.EventSubscriptionEntityManager; IList <ICompensateEventSubscriptionEntity> eventSubscriptions = eventSubscriptionEntityManager.FindCompensateEventSubscriptionsByExecutionId(subProcessExecution.ParentId); if (eventSubscriptions.Count == 0) { Leave(execution); } else { Leave(execution); string deleteReason = History.DeleteReasonFields.BOUNDARY_EVENT_INTERRUPTING + "(" + boundaryEvent.Id + ")"; // cancel boundary is always sync ScopeUtil.ThrowCompensationEvent(eventSubscriptions, execution, false); executionEntityManager.DeleteExecutionAndRelatedData(subProcessExecution, deleteReason, false); if (subProcessExecution.CurrentFlowElement is Activity activity) { if (activity.LoopCharacteristics != null) { IExecutionEntity miExecution = subProcessExecution.Parent; IList <IExecutionEntity> miChildExecutions = executionEntityManager.FindChildExecutionsByParentExecutionId(miExecution.Id); foreach (IExecutionEntity miChildExecution in miChildExecutions) { if (subProcessExecution.Id.Equals(miChildExecution.Id) == false && activity.Id.Equals(miChildExecution.CurrentActivityId)) { executionEntityManager.DeleteExecutionAndRelatedData(miChildExecution, deleteReason, false); } } } } } }