/// <summary> /// Called when [receive]. /// </summary> /// <param name="message">The message.</param> protected void OnReceive(object message) { //note: RemoteDaemon does not handle ActorSelection messages - those are handled directly by the RemoteActorRefProvider. if (message is IDaemonMsg) { Log.Debug("Received command [{0}] to RemoteSystemDaemon on [{1}]", message, Path.Address); if (message is DaemonMsgCreate) { HandleDaemonMsgCreate((DaemonMsgCreate)message); } } //Remote ActorSystem on another process / machine has died. //Need to clean up any references to remote deployments here. else if (message is AddressTerminated) { var addressTerminated = (AddressTerminated)message; //stop any remote actors that belong to this address ForeachActorRef(@ref => { if (@ref.Parent.Path.Address == addressTerminated.Address) { _system.Stop(@ref); } }); } }
/// <summary> /// Tells the internal. /// </summary> /// <param name="message">The message.</param> /// <param name="sender">The sender.</param> protected override void TellInternal(object message, IActorRef sender) { //note: RemoteDaemon does not handle ActorSelection messages - those are handled directly by the RemoteActorRefProvider. if (message is IDaemonMsg) { Log.Debug("Received command [{0}] to RemoteSystemDaemon on [{1}]", message, Path.Address); if (message is DaemonMsgCreate) { HandleDaemonMsgCreate((DaemonMsgCreate)message); } } //Remote ActorSystem on another process / machine has died. //Need to clean up any references to remote deployments here. else if (message is AddressTerminated) { var addressTerminated = (AddressTerminated)message; //stop any remote actors that belong to this address ForEachChild(@ref => { if (@ref.Parent.Path.Address == addressTerminated.Address) { _system.Stop(@ref); } }); } else if (message is Identify) { var identify = message as Identify; sender.Tell(new ActorIdentity(identify.MessageId, this)); } else if (message is TerminationHook) { _terminating.SwitchOn(() => { TerminationHookDoneWhenNoChildren(); ForEachChild(c => _system.Stop(c)); }); } }
/// <summary> /// Tells the internal. /// </summary> /// <param name="message">The message.</param> /// <param name="sender">The sender.</param> protected override void TellInternal(object message, IActorRef sender) { //note: RemoteDaemon does not handle ActorSelection messages - those are handled directly by the RemoteActorRefProvider. if (message is IDaemonMsg) { Log.Debug("Received command [{0}] to RemoteSystemDaemon on [{1}]", message, Path.Address); if (message is DaemonMsgCreate) { HandleDaemonMsgCreate((DaemonMsgCreate)message); } } else if (message is ActorSelectionMessage sel) { var iter = sel.Elements.Iterator(); (IEnumerable <string>, object) Rec(IImmutableList <string> acc) { while (true) { if (iter.IsEmpty()) { return(acc.Reverse(), sel.Message); } // find child elements, and the message to send, which is a remaining ActorSelectionMessage // in case of SelectChildPattern, otherwise the actual message of the selection switch (iter.Next()) { case SelectChildName n: acc = ImmutableList.Create(n.Name).AddRange(acc); continue; case SelectParent p when !acc.Any(): continue; case SelectParent p: acc = acc.Skip(1).ToImmutableList(); continue; case SelectChildPattern pat: return(acc.Reverse(), sel.Copy(elements: new[] { pat }.Concat(iter.ToVector()).ToArray())); default: // compiler ceremony - should never be hit throw new InvalidOperationException("Unknown ActorSelectionPart []"); } } } var t = Rec(ImmutableList <string> .Empty); var concatenatedChildNames = t.Item1; var m = t.Item2; var child = GetChild(concatenatedChildNames); if (child.IsNobody()) { var emptyRef = new EmptyLocalActorRef(_system.Provider, Path / sel.Elements.Select(el => el.ToString()), _system.EventStream); emptyRef.Tell(sel, sender); } else { child.Tell(m, sender); } } //Remote ActorSystem on another process / machine has died. //Need to clean up any references to remote deployments here. else if (message is AddressTerminated) { var addressTerminated = (AddressTerminated)message; //stop any remote actors that belong to this address ForEachChild(@ref => { if (@ref.Parent.Path.Address == addressTerminated.Address) { _system.Stop(@ref); } }); } else if (message is Identify identify) { sender.Tell(new ActorIdentity(identify.MessageId, this)); } else if (message is TerminationHook) { _terminating.SwitchOn(() => { TerminationHookDoneWhenNoChildren(); ForEachChild(c => _system.Stop(c)); }); } }
/// <summary> /// Called when [receive]. /// </summary> /// <param name="message">The message.</param> protected void OnReceive(object message, IActorRef sender) { //note: RemoteDaemon does not handle ActorSelection messages - those are handled directly by the RemoteActorRefProvider. if (message is IDaemonMsg) { Log.Debug("Received command [{0}] to RemoteSystemDaemon on [{1}]", message, Path.Address); if (message is DaemonMsgCreate) { HandleDaemonMsgCreate((DaemonMsgCreate)message); } } //Remote ActorSystem on another process / machine has died. //Need to clean up any references to remote deployments here. else if (message is AddressTerminated) { var addressTerminated = (AddressTerminated)message; //stop any remote actors that belong to this address ForEachChild(@ref => { if (@ref.Parent.Path.Address == addressTerminated.Address) { _system.Stop(@ref); } }); } else if (message is Identify) { var identify = message as Identify; sender.Tell(new ActorIdentity(identify.MessageId, this)); } else if (message is TerminationHook) { _terminating.SwitchOn(() => { TerminationHookDoneWhenNoChildren(); ForEachChild(c => _system.Stop(c)); }); } else if (message is DeathWatchNotification) { var deathWatchNotification = message as DeathWatchNotification; var child = deathWatchNotification.Actor as ActorRefWithCell; if (child != null) { if (child.IsLocal) { // removeChild(child.path.elements.drop(1).mkString("/"), child) // val parent = child.getParent // if (removeChildParentNeedsUnwatch(parent, child)) parent.sendSystemMessage(Unwatch(parent, this)) // terminationHookDoneWhenNoChildren() _terminating.Locked(() => { var name = child.Path.Elements.Drop(1).Join("/"); RemoveChild(name, child); var parent = child.Parent; if (RemoveChildParentNeedsUnwatch(parent, child)) { parent.Tell(new Unwatch(parent, this)); } TerminationHookDoneWhenNoChildren(); }); } } else { //case DeathWatchNotification(parent: ActorRef with ActorRefScope, _, _) if !parent.isLocal ⇒ // terminating.locked { // parent2children.remove(parent) match { // case null ⇒ // case children ⇒ // for (c ← children) { // system.stop(c) // removeChild(c.path.elements.drop(1).mkString("/"), c) // } // terminationHookDoneWhenNoChildren() // } // } var parent = deathWatchNotification.Actor; var parentWithScope = parent as IActorRefScope; if (parentWithScope != null && !parentWithScope.IsLocal) { _terminating.Locked(() => { IImmutableSet <IActorRef> children; if (_parent2Children.TryRemove(parent, out children)) { foreach (var c in children) { _system.Stop(c); var name = c.Path.Elements.Drop(1).Join("/"); RemoveChild(name, c); } TerminationHookDoneWhenNoChildren(); } }); } } } }