示例#1
0
 internal static void PushActorRefToStack(LocalActorRef actorRef)
 {
     InterlockedSpin.Swap(ref _stack, st =>
                          st == null
                                 ? ImmutableStack.Create(actorRef)
                                 : st.Push(actorRef));
 }
示例#2
0
        private void HandleTerminateActor()
        {
            //TODO: UnwatchWatchedActors();

            //Stop all children
            Children.GetChildrenRefs().ForEach(c => c.Stop());

            var actorIsAlreadyTerminating = _actorStatus.IsTerminating;
            //If we have children we must wait for, then set status to Terminating, so we know what to do when all children have terminated
            var weHaveChildrenWeMustWaitFor = InterlockedSpin.ConditionallySwap(ref _actorStatus, _ => Children.HasChildrenThatAreTerminating(), _ => ActorStatus.Terminating);

            if (weHaveChildrenWeMustWaitFor)
            {
                if (!actorIsAlreadyTerminating)
                {
                    //Children were not yet terminated, and this is the first time we try to terminate this actor
                    //We should not not process normal messages while waiting for all children to terminate
                    SuspendThisOnly();

                    // do not propagate failures during shutdown to the supervisor
                    SetFailedPerpatrator(this);
                    if (_system.Settings.DebugLifecycle)
                    {
                        Publish(new DebugLogEvent(_path.ToString(), SafeGetTypeForLogging(), "Stopping"));
                    }
                }
            }
            else
            {
                SetTerminatedChildrenCollection();
                FinishTerminate();
            }
        }
示例#3
0
 internal static void PopActorAndMarkerFromStack()
 {
     InterlockedSpin.Swap(ref _stack, st =>
                          st == null
                                 ? null
                                 : st.Peek() == null       // if first item is null, i.e. a marker
                                         ? st.Pop().Pop()  // then pop that value,
                                         : st.Pop());      // otherwise pop only the actor
 }
示例#4
0
        private bool UpdateChildrenCollection(Func <ChildrenCollection, ChildrenCollection> updater, Predicate <ChildrenCollection> shouldUpdate)
        {
#pragma warning disable 420             //Ok to disregard from CS0420 "a reference to a volatile field will not be treated as volatile" as we're using interlocked underneath, see http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx
            return(InterlockedSpin.ConditionallySwap(ref _childrenDoNotCallMeDirectly, c =>
            {
                if (shouldUpdate(c))
                {
                    var newC = updater(c);
                    return Tuple.Create(true, newC);
                }
                return Tuple.Create(false, c);
            }));

#pragma warning restore 420
        }
示例#5
0
        private void CreateActorInstanceDueToFailure(Exception cause)
        {
            Debug.Assert(_mailbox.IsSuspended, "Mailbox must be suspended during restart, status=" + (_mailbox is MailboxBase ? (_mailbox as MailboxBase).GetMailboxStatusForDebug() : "unknown"));
            Debug.Assert(_failPerpatrator == this, "Perpetrator should be this instance");

            //Stop all children
            Children.GetChildrenRefs().ForEach(c => c.Stop());

            //If we have children we must wait for, then set status to creating, so we know what to do when all children have terminated
            var weHaveChildrenWeMustWaitFor = InterlockedSpin.ConditionallySwap(ref _actorStatus, _ => Children.HasChildrenThatAreTerminating(), ActorStatus.Creating(cause));

            if (!weHaveChildrenWeMustWaitFor)
            {
                FinishCreateActorInstanceDueToFailure(cause);
            }
        }
示例#6
0
        private void RecreateActor(Exception cause)
        {
            if (_actor == null)
            {
                //The actor has not yet been created. We can use a simpler approach
                Publish(new DebugLogEvent(_path.ToString(), SafeGetTypeForLogging(), "Changing recreate into Create after " + cause));
                CreateActorInstanceDueToFailure(cause);
            }
            else if (_actorStatus.IsNotCreatingRecreatingOrTerminating)
            {
                var failedActor = _actor;

                if (failedActor != null)
                {
                    //TODO: Stash optional message
                    object   optionalMessage = null;
                    ActorRef optionalSender  = null;
                    if (_currentMessage != null)
                    {
                        optionalMessage = _currentMessage.Message;
                        optionalSender  = _currentMessage.Sender;
                    }
                    try
                    {
                        try { failedActor.PreRestart(cause, optionalMessage, optionalSender); }
                        catch (Exception e) { Publish(new ErrorLogEvent(_path.ToString(), SafeGetTypeForLogging(failedActor), "Exception thrown during actor.PreRestart()", e)); }
                    }
                    finally
                    {
                        ClearActor(failedActor);
                    }
                    Debug.Assert(_mailbox.IsSuspended, "Mailbox must be suspended during restart, status=" + (_mailbox is MailboxBase ? (_mailbox as MailboxBase).GetMailboxStatusForDebug() : "unknown"));

                    //If we have children we must wait for, then set status to recreating, so we know what to do when all children have terminated
                    var weHaveChildrenWeMustWaitFor = InterlockedSpin.ConditionallySwap(ref _actorStatus, _ => Children.HasChildrenThatAreTerminating(), _ => ActorStatus.Recreating(cause));
                    if (!weHaveChildrenWeMustWaitFor)
                    {
                        //No children we must wait for. Continue with recreating
                        FinishRecreateActor(failedActor, cause);
                    }
                }
            }
            else
            {
                ResumeActor(null);
            }
        }
示例#7
0
 public static void Clear_ForTestingONLY()
 {
     InterlockedSpin.Swap(ref _stack, st => st.Clear());
     InterlockedSpin.Swap(ref _stack, st => st.Clear());
 }
示例#8
0
        private void UpdateChildrenCollection(Func <ChildrenCollection, ChildrenCollection> updater)
        {
#pragma warning disable 420             //Ok to disregard from CS0420 "a reference to a volatile field will not be treated as volatile" as we're using interlocked underneath, see http://msdn.microsoft.com/en-us/library/4bw5ewxy.aspx
            InterlockedSpin.Swap(ref _childrenDoNotCallMeDirectly, updater);
#pragma warning restore 420
        }