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();
                }
            }
        }
예제 #2
0
 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);
        }
예제 #4
0
        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);
            }
        }