private void SendAllToDeadLetters(EarliestFirstSystemMessageList messages)
 {
     if (messages.IsEmpty)
     {
         return;                   // don't run any of this if there are no system messages
     }
     do
     {
         var msg = messages.Head;
         messages = messages.Tail;
         msg.Unlink();
         SystemImpl.Provider.DeadLetters.Tell(msg, Self);
     } while (messages.NonEmpty);
 }
Ejemplo n.º 2
0
        public void SystemMessageList_value_class_must_be_able_to_properly_reverse_contents()
        {
            var create0 = new Failed(null, null, 0);
            var create1 = new Failed(null, null, 1);
            var create2 = new Failed(null, null, 2);
            var list    = LNil + create0 + create1 + create2;
            EarliestFirstSystemMessageList listRev = list.Reverse;

            listRev.IsEmpty.ShouldBeFalse();
            listRev.Size.ShouldBe(3);

            (listRev.Head == create0).ShouldBeTrue();
            (listRev.Tail.Head == create1).ShouldBeTrue();
            (listRev.Tail.Tail.Head == create2).ShouldBeTrue();
            (listRev.Tail.Tail.Tail.Head == null).ShouldBeTrue();

            (create0.Next == create1).ShouldBeTrue();
            (create1.Next == create2).ShouldBeTrue();
            (create2.Next == null).ShouldBeTrue();
        }
        private void SysMsgInvokeAll(EarliestFirstSystemMessageList messages, int currentState)
        {
            while (true)
            {
                var rest    = messages.Tail;
                var message = messages.Head;
                message.Unlink();

                try
                {
                    switch (message)
                    {
                    case SystemMessage sm when ShouldStash(sm, currentState):
                        Stash(message);

                        break;

                    case ActorTaskSchedulerMessage atsm:
                        HandleActorTaskSchedulerMessage(atsm);
                        break;

                    case Failed f:
                        HandleFailed(f);
                        break;

                    case DeathWatchNotification n:
                        WatchedActorTerminated(n.Actor, n.ExistenceConfirmed, n.AddressTerminated);
                        break;

                    case Create c:
                        Create(c.Failure);
                        break;

                    case Watch w:
                        AddWatcher(w.Watchee, w.Watcher);
                        break;

                    case Unwatch uw:
                        RemWatcher(uw.Watchee, uw.Watcher);
                        break;

                    case Recreate r:
                        FaultRecreate(r.Cause);
                        break;

                    case Suspend _:
                        FaultSuspend();
                        break;

                    case Resume r:
                        FaultResume(r.CausedByFailure);
                        break;

                    case Terminate _:
                        Terminate();
                        break;

                    case Supervise s:
                        Supervise(s.Child, s.Async);
                        break;

                    default:
                        throw new NotSupportedException($"Unknown message {message.GetType().Name}");
                    }
                }
                catch (Exception cause)
                {
                    HandleInvokeFailure(cause);
                }

                var nextState = CalculateState();
                // As each state accepts a strict subset of another state, it is enough to unstash if we "walk up" the state
                // chain
                var todo = nextState < currentState ? rest + UnstashAll() : rest;

                if (IsTerminated)
                {
                    SendAllToDeadLetters(todo);
                    break;
                }
                else if (todo.IsEmpty)
                {
                    break;
                }

                currentState = nextState;
                messages     = todo;
            }
        }
Ejemplo n.º 4
0
        private void SysMsgInvokeAll(EarliestFirstSystemMessageList messages, int currentState)
        {
            var nextState = currentState;
            var todo      = messages;

            while (true)
            {
                var m = todo.Head;
                todo = messages.Tail;
                m.Unlink();
                try
                {
                    // TODO: replace with direct cast
                    if (ShouldStash(m, nextState))
                    {
                        Stash(m);
                    }
                    if (m is ActorTaskSchedulerMessage)
                    {
                        HandleActorTaskSchedulerMessage((ActorTaskSchedulerMessage)m);
                    }
                    else if (m is Failed)
                    {
                        HandleFailed(m as Failed);
                    }
                    else if (m is DeathWatchNotification)
                    {
                        var msg = m as DeathWatchNotification;
                        WatchedActorTerminated(msg.Actor, msg.ExistenceConfirmed, msg.AddressTerminated);
                    }
                    else if (m is Create)
                    {
                        Create((m as Create).Failure);
                    }
                    else if (m is Watch)
                    {
                        var watch = m as Watch;
                        AddWatcher(watch.Watchee, watch.Watcher);
                    }
                    else if (m is Unwatch)
                    {
                        var unwatch = m as Unwatch;
                        RemWatcher(unwatch.Watchee, unwatch.Watcher);
                    }
                    else if (m is Recreate)
                    {
                        FaultRecreate((m as Recreate).Cause);
                    }
                    else if (m is Suspend)
                    {
                        FaultSuspend();
                    }
                    else if (m is Resume)
                    {
                        FaultResume((m as Resume).CausedByFailure);
                    }
                    else if (m is Terminate)
                    {
                        Terminate();
                    }
                    else if (m is Supervise)
                    {
                        var supervise = m as Supervise;
                        Supervise(supervise.Child, supervise.Async);
                    }
                    else
                    {
                        throw new NotSupportedException($"Unknown message {m.GetType().Name}");
                    }
                }
                catch (Exception cause)
                {
                    HandleInvokeFailure(cause);
                }

                nextState = CalculateState();
                // As each state accepts a strict subset of another state, it is enough to unstash if we "walk up" the state
                // chain
                todo = nextState < currentState ? todo + UnstashAll() : todo;
                if (IsTerminated)
                {
                    SendAllToDeadLetters(todo);
                    return;
                }
                if (todo.IsEmpty)
                {
                    return;               // keep running until the stash is empty
                }
            }
        }
Ejemplo n.º 5
0
        private void SysMsgInvokeAll(EarliestFirstSystemMessageList messages, int currentState)
        {
            var nextState = currentState;
            var todo      = messages;

            while (true)
            {
                var m = todo.Head;
                todo = messages.Tail;
                m.Unlink();
                try
                {
                    // TODO: replace with direct cast
                    if (ShouldStash(m, nextState))
                    {
                        Stash(m);
                    }

                    switch (m)
                    {
                    case ActorTaskSchedulerMessage message:
                        HandleActorTaskSchedulerMessage(message);
                        break;

                    case Failed failed:
                        HandleFailed(failed);
                        break;

                    case DeathWatchNotification notification:
                    {
                        var msg = notification;
                        WatchedActorTerminated(msg.Actor, msg.ExistenceConfirmed, msg.AddressTerminated);
                        break;
                    }

                    case Create create:
                        Create(create.Failure);
                        break;

                    case Watch watch1:
                    {
                        var watch = watch1;
                        AddWatcher(watch.Watchee, watch.Watcher);
                        break;
                    }

                    case Unwatch unwatch1:
                    {
                        var unwatch = unwatch1;
                        RemWatcher(unwatch.Watchee, unwatch.Watcher);
                        break;
                    }

                    case Recreate recreate:
                        FaultRecreate(recreate.Cause);
                        break;

                    case Suspend _:
                        FaultSuspend();
                        break;

                    case Resume resume:
                        FaultResume(resume.CausedByFailure);
                        break;

                    case Terminate _:
                        Terminate();
                        break;

                    case Supervise supervise1:
                    {
                        var supervise = supervise1;
                        Supervise(supervise.Child, supervise.Async);
                        break;
                    }

                    default:
                        throw new NotSupportedException($"Unknown message {m.GetType().Name}");
                    }
                }
                catch (Exception cause)
                {
                    HandleInvokeFailure(cause);
                }

                nextState = CalculateState();
                // As each state accepts a strict subset of another state, it is enough to unstash if we "walk up" the state
                // chain
                todo = nextState < currentState ? todo + UnstashAll() : todo;
                if (IsTerminated)
                {
                    SendAllToDeadLetters(todo);
                    return;
                }
                if (todo.IsEmpty)
                {
                    return;               // keep running until the stash is empty
                }
            }
        }