Add UID to RemoteActorRef, see #3072
* Sending to a previous incarnation of an actor shall fail, to make remote actors work the same way as local ones (in the sense that after Terminated() the ref is not working anymore) * Changed equality of ActorRef to take the uid into account * Parse uid fragment in RelativeActorPath and ActorPathExtractor * Handle uid in getChild and in RemoteSystemDaemon * Use toSerializationFormat and toSerializationFormatWithAddress in serialization * Replaced var uid in ActorCell and ChildRestartStats with constructor parameters (path) * Create the uid in one single place, in makeChild in parent * Handle ActorRef with and without uid in DeathWatch * Optimize ActorPath.toString and friends * Update documentation and migration guide
This commit is contained in:
parent
eb10fac787
commit
b738487dc8
37 changed files with 607 additions and 186 deletions
|
|
@ -12,6 +12,7 @@ import akka.dispatch.Watch
|
|||
import akka.actor.ActorRefWithCell
|
||||
import akka.actor.ActorRefScope
|
||||
import akka.util.Switch
|
||||
import akka.actor.RootActorPath
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
|
|
@ -54,11 +55,14 @@ private[akka] class RemoteSystemDaemon(
|
|||
|
||||
@tailrec
|
||||
def rec(s: String, n: Int): (InternalActorRef, Int) = {
|
||||
getChild(s) match {
|
||||
import akka.actor.ActorCell._
|
||||
val (childName, uid) = splitNameAndUid(s)
|
||||
getChild(childName) match {
|
||||
case null ⇒
|
||||
val last = s.lastIndexOf('/')
|
||||
if (last == -1) (Nobody, n)
|
||||
else rec(s.substring(0, last), n + 1)
|
||||
case ref if uid != undefinedUid && uid != ref.path.uid ⇒ (Nobody, n)
|
||||
case ref ⇒ (ref, n)
|
||||
}
|
||||
}
|
||||
|
|
@ -82,15 +86,21 @@ private[akka] class RemoteSystemDaemon(
|
|||
// TODO RK currently the extracted “address” is just ignored, is that okay?
|
||||
// TODO RK canonicalize path so as not to duplicate it always #1446
|
||||
val subpath = elems.drop(1)
|
||||
val path = this.path / subpath
|
||||
val p = this.path / subpath
|
||||
val childName = {
|
||||
val s = subpath.mkString("/")
|
||||
val i = s.indexOf('#')
|
||||
if (i < 0) s
|
||||
else s.substring(0, i)
|
||||
}
|
||||
val isTerminating = !terminating.whileOff {
|
||||
val actor = system.provider.actorOf(system, props, supervisor.asInstanceOf[InternalActorRef],
|
||||
path, systemService = false, Some(deploy), lookupDeploy = true, async = false)
|
||||
addChild(subpath.mkString("/"), actor)
|
||||
p, systemService = false, Some(deploy), lookupDeploy = true, async = false)
|
||||
addChild(childName, actor)
|
||||
actor.sendSystemMessage(Watch(actor, this))
|
||||
actor.start()
|
||||
}
|
||||
if (isTerminating) log.error("Skipping [{}] to RemoteSystemDaemon on [{}] while terminating", message, path.address)
|
||||
if (isTerminating) log.error("Skipping [{}] to RemoteSystemDaemon on [{}] while terminating", message, p.address)
|
||||
case _ ⇒
|
||||
log.debug("remote path does not match path from message [{}]", message)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue