/// <summary>
        /// TBD
        /// </summary>
        /// <param name="actor">TBD</param>
        protected void UnwatchWatchedActors(ActorBase actor)
        {
            var watching = _state
                           .GetWatching()
                           .ToList();

            if (!watching.Any())
            {
                return;
            }

            MaintainAddressTerminatedSubscription(() =>
            {
                try
                {
                    // ➡➡➡ NEVER SEND THE SAME SYSTEM MESSAGE OBJECT TO TWO ACTORS
                    foreach (var watchee in watching.OfType <IInternalActorRef>())
                    {
                        watchee.SendSystemMessage(new Unwatch(watchee, _self));
                    }
                }
                finally
                {
                    _state = _state.ClearWatching();
                    _state = _state.ClearTerminated();
                }
            });
        }
Example #2
0
        /// <summary>
        /// TBD
        /// </summary>
        protected void TellWatchersWeDied()
        {
            var watchedBy = _state
                            .GetWatchedBy()
                            .ToList();

            if (watchedBy.Count == 0)
            {
                return;
            }
            try
            {
                // Don't need to send to parent parent since it receives a DWN by default

                /*
                 * It is important to notify the remote watchers first, otherwise RemoteDaemon might shut down, causing
                 * the remoting to shut down as well. At this point Terminated messages to remote watchers are no longer
                 * deliverable.
                 *
                 * The problematic case is:
                 *  1. Terminated is sent to RemoteDaemon
                 *   1a. RemoteDaemon is fast enough to notify the terminator actor in RemoteActorRefProvider
                 *   1b. The terminator is fast enough to enqueue the shutdown command in the remoting
                 *  2. Only at this point is the Terminated (to be sent remotely) enqueued in the mailbox of remoting
                 *
                 * If the remote watchers are notified first, then the mailbox of the Remoting will guarantee the correct order.
                 */
                foreach (var w in watchedBy)
                {
                    SendTerminated(false, (IInternalActorRef)w);
                }
                foreach (var w in watchedBy)
                {
                    SendTerminated(true, (IInternalActorRef)w);
                }
            }
            finally
            {
                _state = _state.ClearWatching();
            }
        }