protected internal override PvmExecutionImpl EventNotificationsStarted(PvmExecutionImpl execution)
        {
            execution.IncrementSequenceCounter();

            // hack around execution tree structure not being in sync with activity instance concept:
            // if we end a scope activity, take remembered activity instance from parent and set on
            // execution before calling END listeners.
            var          parent   = execution.Parent;
            IPvmActivity activity = execution.Activity;

            if ((parent != null) && execution.IsScope && (activity != null) && activity.IsScope &&
                (activity.ActivityBehavior is ICompositeActivityBehavior ||
                 (CompensationBehavior.IsCompensationThrowing(execution) &&
                  !LegacyBehavior.IsCompensationThrowing(execution))))
            {
                Log.DebugLeavesActivityInstance(execution, execution.ActivityInstanceId);

                // use remembered activity instance id from parent
                execution.ActivityInstanceId = parent.ActivityInstanceId;
                // make parent go one scope up.
                parent.LeaveActivityInstance();
            }

            return(execution);
        }
        protected internal virtual bool CanHaveChildScopes(PvmExecutionImpl execution)
        {
            IPvmActivity activity = execution.Activity;

            return(activity.ActivityBehavior is ICompositeActivityBehavior ||
                   CompensationBehavior.IsCompensationThrowing(execution));
        }
Exemple #3
0
 /// <summary>
 ///     event-scope executions are not considered in this mapping and must be ignored
 /// </summary>
 protected internal virtual bool IsLeaf(IActivityExecution execution)
 {
     if (CompensationBehavior.IsCompensationThrowing((PvmExecutionImpl)execution))
     {
         return(true);
     }
     return(!execution.IsEventScope && execution.NonEventScopeExecutions.Count == 0);
 }
Exemple #4
0
 /// <summary>
 /// event-scope executions are not considered in this mapping and must be ignored
 /// </summary>
 protected internal virtual bool isLeaf(ExecutionEntity execution)
 {
     if (CompensationBehavior.isCompensationThrowing(execution))
     {
         return(true);
     }
     else
     {
         return(!execution.EventScope && execution.NonEventScopeExecutions.Count == 0);
     }
 }
Exemple #5
0
        protected internal override void EventNotificationsCompleted(PvmExecutionImpl execution)
        {
            IPvmActivity activity = execution.Activity;

            if (execution.IsScope && (ExecutesNonScopeActivity(execution) || IsAsyncBeforeActivity(execution)) &&
                !CompensationBehavior.executesNonScopeCompensationHandler(execution))
            {
                // case this is a scope execution and the activity is not a scope
                execution.LeaveActivityInstance();
                execution.Activity = (GetFlowScopeActivity(activity));
                execution.PerformOperation(PvmAtomicOperationFields.DeleteCascadeFireActivityEnd);
            }
            else
            {
                if (execution.IsScope)
                {
                    execution.Destroy();
                }

                // remove this execution and its concurrent parent (if exists)
                execution.Remove();

                var continueRemoval = !execution.IsDeleteRoot;

                if (continueRemoval)
                {
                    var propagatingExecution = execution.Parent;
                    if ((propagatingExecution != null) && !propagatingExecution.IsScope &&
                        !propagatingExecution.HasChildren())
                    {
                        propagatingExecution.Remove();
                        continueRemoval      = !propagatingExecution.IsDeleteRoot;
                        propagatingExecution = propagatingExecution.Parent;
                    }

                    if (continueRemoval)
                    {
                        if (propagatingExecution != null)
                        {
                            // continue deletion with the next scope execution
                            // set activity on parent in case the parent is an inactive scope execution and activity has been set to 'null'.
                            if ((propagatingExecution.Activity == null) && (activity != null) &&
                                (activity.FlowScope != null))
                            {
                                propagatingExecution.Activity = (GetFlowScopeActivity(activity));
                            }
                            ((PvmExecutionImpl)propagatingExecution).PerformOperation(PvmAtomicOperationFields.DeleteCascade);
                        }
                    }
                }
            }
        }
Exemple #6
0
        protected internal virtual bool isAncestorCompensationThrowing(ActivityExecution execution)
        {
            ActivityExecution parent = execution.Parent;

            while (parent != null)
            {
                if (CompensationBehavior.isCompensationThrowing((PvmExecutionImpl)parent))
                {
                    return(true);
                }
                parent = parent.Parent;
            }
            return(false);
        }
Exemple #7
0
        protected internal virtual IList <ExecutionEntity> FilterLeaves(IList <ExecutionEntity> executionList)
        {
            IList <ExecutionEntity> leaves = new List <ExecutionEntity>();

            foreach (var execution in executionList)
            {
                // although executions executing throwing compensation events are not leaves in the tree,
                // they are treated as leaves since their child executions are logical children of their parent scope execution
                if (execution.NonEventScopeExecutions.Count == 0 || CompensationBehavior.IsCompensationThrowing(execution))
                {
                    leaves.Add(execution);
                }
            }
            return(leaves);
        }
        protected internal virtual void InitActivityInstanceEvent(HistoricActivityInstanceEventEntity evt, ExecutionEntity execution, IHistoryEventType eventType)
        {
            IPvmScope eventSource = execution.Activity;

            if (eventSource == null)
            {
                eventSource = (IPvmScope)execution.EventSource;
            }
            string activityInstanceId = execution.ActivityInstanceId;

            string          parentActivityInstanceId = null;
            ExecutionEntity parentExecution          = (ExecutionEntity)execution.Parent;

            if (parentExecution != null && CompensationBehavior.IsCompensationThrowing(parentExecution) && execution.Activity != null)
            {
                parentActivityInstanceId = CompensationBehavior.GetParentActivityInstanceId(execution);
            }
            else
            {
                parentActivityInstanceId = execution.ParentActivityInstanceId;
            }

            InitActivityInstanceEvent(evt, execution, eventSource, activityInstanceId, parentActivityInstanceId, eventType);
        }
Exemple #9
0
        public virtual IActivityInstance Execute(CommandContext commandContext)
        {
            EnsureUtil.EnsureNotNull("processInstanceId", ProcessInstanceId);
            IList <ExecutionEntity> executionList = LoadProcessInstance(ProcessInstanceId, commandContext);

            if (executionList.Count == 0)
            {
                return(null);
            }

            CheckGetActivityInstance(ProcessInstanceId, commandContext);

            IList <ExecutionEntity> nonEventScopeExecutions = FilterNonEventScopeExecutions(executionList);
            IList <ExecutionEntity> leaves = FilterLeaves(nonEventScopeExecutions);//.OrderBy(m => m.Id).ToList();

            // Leaves must be ordered in a predictable way (e.g. by ID)
            // in order to return a stable execution tree with every repeated invocation of this command.
            // For legacy process instances, there may miss scope executions for activities that are now a scope.
            // In this situation, there may be multiple scope candidates for the same instance id; which one
            // can depend on the order the leaves are iterated.
            OrderById(leaves);

            ExecutionEntity processInstance = FilterProcessInstance(executionList);

            if (processInstance.IsEnded)
            {
                return(null);
            }

            //create act instance for process instance

            ActivityInstanceImpl processActInst = CreateActivityInstance(processInstance, processInstance.ProcessDefinition, ProcessInstanceId, null);
            IDictionary <string, ActivityInstanceImpl> activityInstances = new Dictionary <string, ActivityInstanceImpl>();

            activityInstances[ProcessInstanceId] = processActInst;

            IDictionary <string, TransitionInstanceImpl> transitionInstances = new Dictionary <string, TransitionInstanceImpl>();

            foreach (ExecutionEntity leaf in leaves)
            {
                // skip leafs without activity, e.g. if only the process instance exists after cancellation
                // it will not have an activity set
                if (leaf.Activity == null)
                {
                    continue;
                }

                IDictionary <ScopeImpl, PvmExecutionImpl> activityExecutionMapping = leaf.CreateActivityExecutionMapping();
                IDictionary <ScopeImpl, PvmExecutionImpl> scopeInstancesToCreate   = new Dictionary <ScopeImpl, PvmExecutionImpl>(activityExecutionMapping);

                // create an activity/transition instance for each leaf that executes a non-scope activity
                // and does not throw compensation
                if (leaf.ActivityInstanceId != null)
                {
                    if (!CompensationBehavior.IsCompensationThrowing(leaf) || LegacyBehavior.IsCompensationThrowing(leaf, activityExecutionMapping))
                    {
                        string parentActivityInstanceId = null;

                        parentActivityInstanceId = activityExecutionMapping[leaf.Activity.FlowScope].ParentActivityInstanceId;

                        ActivityInstanceImpl leafInstance = CreateActivityInstance(leaf, (ScopeImpl)leaf.Activity, leaf.ActivityInstanceId, parentActivityInstanceId);
                        activityInstances[leafInstance.Id] = leafInstance;

                        scopeInstancesToCreate.Remove((ScopeImpl)leaf.Activity);
                    }
                }
                else
                {
                    TransitionInstanceImpl transitionInstance = CreateTransitionInstance(leaf);
                    transitionInstances[transitionInstance.Id] = transitionInstance;

                    scopeInstancesToCreate.Remove((ScopeImpl)leaf.Activity);
                }

                LegacyBehavior.RemoveLegacyNonScopesFromMapping(scopeInstancesToCreate);
                scopeInstancesToCreate.Remove(leaf.ProcessDefinition);

                // create an activity instance for each scope (including compensation throwing executions)
                foreach (KeyValuePair <ScopeImpl, PvmExecutionImpl> scopeExecutionEntry in scopeInstancesToCreate)
                {
                    ScopeImpl        scope          = scopeExecutionEntry.Key;
                    PvmExecutionImpl scopeExecution = scopeExecutionEntry.Value;

                    string activityInstanceId       = null;
                    string parentActivityInstanceId = null;

                    activityInstanceId       = scopeExecution.ParentActivityInstanceId;
                    parentActivityInstanceId = activityExecutionMapping[scope.FlowScope].ParentActivityInstanceId;

                    if (activityInstances.ContainsKey(activityInstanceId))
                    {
                        continue;
                    }
                    else
                    {
                        // regardless of the tree structure (compacted or not), the scope's activity instance id
                        // is the activity instance id of the parent execution and the parent activity instance id
                        // of that is the actual parent activity instance id
                        ActivityInstanceImpl scopeInstance = CreateActivityInstance(scopeExecution, scope, activityInstanceId, parentActivityInstanceId);
                        activityInstances[activityInstanceId] = scopeInstance;
                    }
                }
            }

            LegacyBehavior.RepairParentRelationships(activityInstances.Values, ProcessInstanceId);
            PopulateChildInstances(activityInstances, transitionInstances);

            return(processActInst);
        }
Exemple #10
0
        protected internal override void eventNotificationsCompleted(PvmExecutionImpl execution)
        {
            PvmActivity activity = execution.getActivity();

            if (execution.Scope && (executesNonScopeActivity(execution) || isAsyncBeforeActivity(execution)) && !CompensationBehavior.executesNonScopeCompensationHandler(execution))
            {
                execution.removeAllTasks();
                // case this is a scope execution and the activity is not a scope
                execution.leaveActivityInstance();
                execution.setActivity(getFlowScopeActivity(activity));
                execution.performOperation(PvmAtomicOperation_Fields.DELETE_CASCADE_FIRE_ACTIVITY_END);
            }
            else
            {
                if (execution.Scope)
                {
                    execution.destroy();
                }

                // remove this execution and its concurrent parent (if exists)
                execution.remove();

                bool continueRemoval = !execution.DeleteRoot;

                if (continueRemoval)
                {
                    PvmExecutionImpl propagatingExecution = execution.Parent;
                    if (propagatingExecution != null && !propagatingExecution.Scope && !propagatingExecution.hasChildren())
                    {
                        propagatingExecution.remove();
                        continueRemoval      = !propagatingExecution.DeleteRoot;
                        propagatingExecution = propagatingExecution.Parent;
                    }

                    if (continueRemoval)
                    {
                        if (propagatingExecution != null)
                        {
                            // continue deletion with the next scope execution
                            // set activity on parent in case the parent is an inactive scope execution and activity has been set to 'null'.
                            if (propagatingExecution.getActivity() == null && activity != null && activity.FlowScope != null)
                            {
                                propagatingExecution.setActivity(getFlowScopeActivity(activity));
                            }
                        }
                    }
                }
            }
        }