protected internal virtual void HandleChildRemovalInScope(ExecutionEntity removedExecution) { // TODO: the following should be closer to PvmAtomicOperationDeleteCascadeFireActivityEnd // (note though that e.g. boundary events expect concurrent executions to be preserved) // // Idea: attempting to prune and synchronize on the parent is the default behavior when // a concurrent child is removed, but scope activities implementing ModificationObserverBehavior // override this default (and thereforemust* take care of reorganization themselves) // notify the behavior that a concurrent execution has been removed // must be set due to deleteCascade behavior ActivityImpl activity = removedExecution.Activity as ActivityImpl; ScopeImpl flowScope = activity.FlowScope; IActivityExecution scopeExecution = removedExecution.GetParentScopeExecution(false); IActivityExecution executionInParentScope = removedExecution.IsConcurrent ? removedExecution : removedExecution.Parent; if (flowScope.ActivityBehavior != null && flowScope.ActivityBehavior is IModificationObserverBehavior) { // let child removal be handled by the scope itself IModificationObserverBehavior behavior = (IModificationObserverBehavior)flowScope.ActivityBehavior; behavior.DestroyInnerInstance(executionInParentScope); } else { if (executionInParentScope.IsConcurrent) { executionInParentScope.Remove(); scopeExecution.TryPruneLastConcurrentChild(); scopeExecution.ForceUpdate(); } } }
public virtual void ConcurrentChildExecutionEnded(IActivityExecution scopeExecution, IActivityExecution endedExecution) { // join endedExecution.Remove(); scopeExecution.TryPruneLastConcurrentChild(); scopeExecution.ForceUpdate(); }
protected internal virtual IActivityExecution CreateConcurrentExecution(IActivityExecution scopeExecution) { var concurrentChild = scopeExecution.CreateExecution(); scopeExecution.ForceUpdate(); concurrentChild.IsConcurrent = true; concurrentChild.IsScope = false; return(concurrentChild); }
public static bool EventSubprocessConcurrentChildExecutionEnded(IActivityExecution scopeExecution, IActivityExecution endedExecution) { var performLegacyBehavior = IsLegacyBehaviorRequired(endedExecution); if (performLegacyBehavior) { Log.EndConcurrentExecutionInEventSubprocess(); // notify the grandparent flow scope in a similar way PvmAtomicOperationAcitivtyEnd does var flowScope = endedExecution.Activity.FlowScope; if (flowScope != null) { flowScope = flowScope.FlowScope; if (flowScope != null) { if (flowScope == endedExecution.Activity.ProcessDefinition) { endedExecution.Remove(); scopeExecution.TryPruneLastConcurrentChild(); scopeExecution.ForceUpdate(); } else { var flowScopeActivity = (IPvmActivity)flowScope; var activityBehavior = flowScopeActivity.ActivityBehavior; if (activityBehavior is ICompositeActivityBehavior) { ((ICompositeActivityBehavior)activityBehavior).ConcurrentChildExecutionEnded( scopeExecution, endedExecution); } } } } } return(performLegacyBehavior); }
public override void ConcurrentChildExecutionEnded(IActivityExecution scopeExecution, IActivityExecution endedExecution) { int nrOfCompletedInstances = GetLoopVariable(scopeExecution, NumberOfCompletedInstances) + 1; SetLoopVariable(scopeExecution, NumberOfCompletedInstances, nrOfCompletedInstances); int nrOfActiveInstances = GetLoopVariable(scopeExecution, NumberOfActiveInstances) - 1; SetLoopVariable(scopeExecution, NumberOfActiveInstances, nrOfActiveInstances); // inactivate the concurrent execution endedExecution.InActivate(); endedExecution.ActivityInstanceId = null; // join scopeExecution.ForceUpdate(); // TODO: should the completion condition be evaluated on the scopeExecution or on the endedExecution? if (CompletionConditionSatisfied(endedExecution) || AllExecutionsEnded(scopeExecution, endedExecution)) { var childExecutions = new List <IActivityExecution>(((PvmExecutionImpl)scopeExecution).NonEventScopeExecutions); foreach (var childExecution in childExecutions) { if (childExecution.IsActive || (childExecution.Activity == null)) { ((PvmExecutionImpl)childExecution).DeleteCascade( "Multi instance completion condition satisfied."); } else { childExecution.Remove(); } } scopeExecution.Activity = (IPvmActivity)endedExecution.Activity.FlowScope; scopeExecution.IsActive = true; Leave(scopeExecution); } }