示例#1
0
        /// <summary>
        /// Creates a new State computation that is primed with the data of a particular
        /// failure event.
        /// </summary>
        /// <param name="strategy">Strategy as a State computation</param>
        /// <param name="pid">Process ID that failed</param>
        /// <param name="sender">Process that sent the message that cause the failure</param>
        /// <param name="parent">Supervisor of the failed Process</param>
        /// <param name="siblings">The siblings of the failed Process</param>
        /// <param name="ex">Exception</param>
        /// <param name="msg">Message that caused the failure</param>
        /// <returns>State computation that can be invoked by passing it
        /// an object of StrategyState.  This will result in a StateResult that contains
        /// the mutated StrategyState and a StrategyDecision.  The StrategyDecision
        /// contains all the information needed to decide the fate of a Process (and
        /// related processes)</returns>
        public static State <StrategyState, StrategyDecision> Failure(
            this State <StrategyContext, Unit> strategy,
            ProcessId pid,
            ProcessId sender,
            ProcessId parent,
            IEnumerable <ProcessId> siblings,
            Exception ex,
            object msg
            )
        {
            return(stateInst =>
            {
                var now = DateTime.UtcNow;

                var state = strategy(StrategyContext.Empty.With(
                                         Global: stateInst.With(Failures: stateInst.Failures + 1),
                                         FailedProcess: pid,
                                         ParentProcess: parent,
                                         Sender: sender,
                                         Siblings: siblings,
                                         Exception: ex,
                                         Message: msg)).State;

                var decision = new StrategyDecision(
                    state.Directive.IfNone(Directive.Restart),
                    state.MessageDirective.IfNone(MessageDirective.ForwardToDeadLetters),
                    state.Affects,
                    state.Pause
                    );

                return StateResult.Return(state.Global.With(LastFailure: now), decision);
            });
        }
示例#2
0
        InboxDirective RunMessageDirective(
            ProcessId pid,
            ProcessId sender,
            StrategyDecision decision,
            Exception e,
            object message
            )
        {
            var directive = decision.MessageDirective;

            switch (directive.Type)
            {
            case MessageDirectiveType.ForwardToParent:
                tell(pid.Parent(), message, sender);
                return(InboxDirective.Default);

            case MessageDirectiveType.ForwardToSelf:
                tell(pid, message, sender);
                return(InboxDirective.Default);

            case MessageDirectiveType.ForwardToProcess:
                tell((directive as ForwardToProcess).ProcessId, message, sender);
                return(InboxDirective.Default);

            case MessageDirectiveType.StayInQueue:
                return(InboxDirective.PushToFrontOfQueue);

            default:
                tell(ActorContext.DeadLetters, DeadLetter.create(sender, pid, e, "Process error: ", message));
                return(InboxDirective.Default);
            }
        }
示例#3
0
        /// <summary>
        /// Creates a new State computation that is primed with the data of a particular
        /// failure event.  
        /// </summary>
        /// <param name="strategy">Strategy as a State computation</param>
        /// <param name="pid">Process ID that failed</param>
        /// <param name="sender">Process that sent the message that cause the failure</param>
        /// <param name="parent">Supervisor of the failed Process</param>
        /// <param name="siblings">The siblings of the failed Process</param>
        /// <param name="ex">Exception</param>
        /// <param name="msg">Message that caused the failure</param>
        /// <returns>State computation that can be invoked by passing it
        /// an object of StrategyState.  This will result in a StateResult that contains
        /// the mutated StrategyState and a StrategyDecision.  The StrategyDecision 
        /// contains all the information needed to decide the fate of a Process (and
        /// related processes)</returns>
        public static State<StrategyState, StrategyDecision> Failure(
            this State<StrategyContext, Unit> strategy,
            ProcessId pid,
            ProcessId sender,
            ProcessId parent,
            IEnumerable<ProcessId> siblings,
            Exception ex,
            object msg
            )
        {
            return stateInst =>
            {
                var now = DateTime.UtcNow;

                var state = strategy(StrategyContext.Empty.With(
                    Global: stateInst.With(Failures: stateInst.Failures + 1),
                    FailedProcess: pid,
                    ParentProcess: parent,
                    Sender: sender,
                    Siblings: siblings,
                    Exception: ex,
                    Message: msg)).State;

                var decision = new StrategyDecision(
                    state.Directive.IfNone(Directive.Restart),
                    state.MessageDirective.IfNone(MessageDirective.ForwardToDeadLetters),
                    state.Affects,
                    state.Pause
                );

                return StateResult.Return(state.Global.With(LastFailure: now), decision);
            };
        }
示例#4
0
        void RunProcessDirective(
            ProcessId pid,
            ProcessId sender,
            Exception e,
            object message,
            StrategyDecision decision
            )
        {
            var directive = decision.ProcessDirective;

            // Find out the processes that this strategy affects and apply
            foreach (var cpid in decision.Affects.Filter(x => x != pid))
            {
                switch (directive.Type)
                {
                case DirectiveType.Escalate:
                case DirectiveType.Resume:
                    unpause(cpid);
                    break;

                case DirectiveType.Restart:
                    restart(cpid);
                    break;

                case DirectiveType.Stop:
                    kill(cpid);
                    break;
                }
            }

            unpause(pid);

            switch (directive.Type)
            {
            case DirectiveType.Escalate:
                tellSystem(Parent.Actor.Id, SystemMessage.ChildFaulted(pid, sender, e, message), Self);
                break;

            case DirectiveType.Resume:
                // Do nothing
                break;

            case DirectiveType.Restart:
                Restart();
                break;

            case DirectiveType.Stop:
                ShutdownProcess(false);
                break;
            }
        }