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();
 }
        public override void DestroyInnerInstance(IActivityExecution concurrentExecution)
        {
            var scopeExecution = concurrentExecution.Parent;

            concurrentExecution.Remove();
            scopeExecution.ForceUpdate();

            var nrOfActiveInstances = GetLoopVariable(scopeExecution, NumberOfActiveInstances);

            SetLoopVariable(scopeExecution, NumberOfActiveInstances, nrOfActiveInstances - 1);
        }
        protected internal virtual void SignalCompensationDone(IActivityExecution execution)
        {
            // default behavior is to join compensating executions and propagate the signal if all executions have compensated

            // only wait for non-event-scope executions cause a compensation event subprocess consume the compensation event and
            // do not have to compensate embedded subprocesses (which are still non-event-scope executions)

            if (((PvmExecutionImpl)execution).NonEventScopeExecutions.Count == 0)
            {
                if (execution.Parent != null)
                {
                    var parent = execution.Parent;
                    execution.Remove();
                    parent.Signal(CompensationUtil.SignalCompensationDone, null);
                }
            }
        }
예제 #5
0
        /// <summary>
        ///     Tolerates the broken execution trees fixed with CAM-3727 where there may be more
        ///     ancestor scope executions than ancestor flow scopes;
        ///     In that case, the argument execution is removed, the parent execution of the argument
        ///     is returned such that one level of mismatch is corrected.
        ///     Note that this does not necessarily skip the correct scope execution, since
        ///     the broken parent-child relationships may be anywhere in the tree (e.g. consider a non-interrupting
        ///     boundary event followed by a subprocess (i.e. scope), when the subprocess ends, we would
        ///     skip the subprocess's execution).
        /// </summary>
        public static IActivityExecution DeterminePropagatingExecutionOnEnd(IActivityExecution propagatingExecution,
                                                                            IDictionary <ScopeImpl, PvmExecutionImpl> activityExecutionMapping)
        {
            if (!propagatingExecution.IsScope)
            {
                return(propagatingExecution);
            }
            // superfluous scope executions won't be contained in the activity-execution mapping
            if (activityExecutionMapping.Values.Contains((PvmExecutionImpl)propagatingExecution))
            {
                return(propagatingExecution);
            }
            // skip one scope
            propagatingExecution.Remove();
            var parent = propagatingExecution.Parent;

            parent.Activity = (propagatingExecution.Activity);
            return(propagatingExecution.Parent);
        }
예제 #6
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);
        }
예제 #7
0
 public void ConcurrentChildExecutionEnded(IActivityExecution scopeExecution, IActivityExecution endedExecution)
 {
     endedExecution.Remove();
     scopeExecution.TryPruneLastConcurrentChild();
 }