Beispiel #1
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);
        }
            /**********************************************************************************/
            // Functions
            /**********************************************************************************/

            public ExecutionSession(IUnitOfWork uow,
                                    OperationalStateCM.ActivityCallStack callStack,
                                    ContainerDO container,
                                    IActivity activity,
                                    ICrateManager crateManager,
                                    IUtilizationMonitoringService utilizationMonitoringService,
                                    IActivityExecutionRateLimitingService activityRateLimiter)
            {
                _uow       = uow;
                _callStack = callStack;
                _container = container;

                _activity = activity;
                _crate    = crateManager;
                _utilizationMonitoringService = utilizationMonitoringService;
                _activityRateLimiter          = activityRateLimiter;
            }