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:
Patrik Nordwall 2013-03-13 16:01:57 +01:00
parent eb10fac787
commit b738487dc8
37 changed files with 607 additions and 186 deletions

View file

@ -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)
}