/**********************************************************************************/

            private void AddNodeForExecution(Guid nodeId)
            {
                var    node     = _uow.PlanRepository.GetById <PlanNodeDO>(nodeId);
                string nodeName = "undefined";

                if (node is ActivityDO)
                {
                    var activityTemplate = _uow.ActivityTemplateRepository.GetByKey(((ActivityDO)node).ActivityTemplateId);
                    nodeName = "Activity: " + activityTemplate.Name + " Version:" + activityTemplate.Version;
                }

                if (node is SubplanDO)
                {
                    nodeName = "Subplan: " + ((SubplanDO)node).Name;
                }

                var frame = new OperationalStateCM.StackFrame
                {
                    NodeId    = nodeId,
                    NodeName  = nodeName,
                    LocalData = _bypassData
                };

                _callStack.PushFrame(frame);
                _bypassData = null;
            }
Beispiel #2
0
        // Previously we were using CurrentActivityId to track container execution.
        // To better accomodate new requirements we changed CurrentActivityId to the Call Stack.
        // But we still can have pending plans in our DB that were created using CurrentActivityId as the main driven logic.
        // To be able to continue executuion of those plans we have the following method.
        // This methods takes CurrentActivityId of the plan and build a call stack using this Id and Plan structure.
        // As the result we will have correct call stack for the plan that was suspended at the node CurrentActivityId.
        // After call stack restoration CurrentActivityId is no longer needed.
        private OperationalStateCM.ActivityCallStack RecoverCallStack(IUnitOfWork uow, ContainerDO curContainerDo)
        {
            var node = uow.PlanRepository.GetById <PlanNodeDO>(curContainerDo.CurrentActivityId);

            if (node == null)
            {
                throw new InvalidOperationException($"Failed to restore call stack from CurrentPlanNodeId. Node {curContainerDo.CurrentActivityId} was not found.");
            }

            var callStack  = new OperationalStateCM.ActivityCallStack();
            var pathToRoot = new List <OperationalStateCM.StackFrame>();

            while (node != null && !(node is PlanDO))
            {
                string nodeName = "undefined";

                if (node is ActivityDO)
                {
                    var activityTemplate = uow.ActivityTemplateRepository.GetByKey(((ActivityDO)node).ActivityTemplateId);
                    nodeName = "Activity: " + activityTemplate.Name + " Version:" + activityTemplate.Version;
                }

                if (node is SubplanDO)
                {
                    nodeName = "Subplan: " + ((SubplanDO)node).Name;
                }

                pathToRoot.Add(new OperationalStateCM.StackFrame
                {
                    NodeName = nodeName,
                    CurrentActivityExecutionPhase = OperationalStateCM.ActivityExecutionPhase.ProcessingChildren,
                    NodeId = node.Id
                });

                node = node.ParentPlanNode;
            }

            for (int i = pathToRoot.Count - 1; i >= 1; i--)
            {
                pathToRoot[i].CurrentChildId = pathToRoot[i - 1].NodeId;
                callStack.PushFrame(pathToRoot[i]);
            }

            callStack.PushFrame(pathToRoot[0]);
            callStack.TopFrame.CurrentActivityExecutionPhase = OperationalStateCM.ActivityExecutionPhase.WasNotExecuted;

            using (var storage = _crate.UpdateStorage(() => curContainerDo.CrateStorage))
            {
                var operationalState = storage.CrateContentsOfType <OperationalStateCM>().Single();
                operationalState.CallStack = callStack;
            }

            curContainerDo.CurrentActivityId = null;
            curContainerDo.NextActivityId    = null;
            curContainerDo.CurrentPlanNode   = null;
            curContainerDo.NextRouteNode     = null;

            return(callStack);
        }