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

@ -241,7 +241,8 @@ private[akka] class RemoteActorRefProvider(
} else {
try {
val localAddress = transport.localAddressForRemote(addr)
val rpath = RootActorPath(addr) / "remote" / localAddress.protocol / localAddress.hostPort / path.elements
val rpath = (RootActorPath(addr) / "remote" / localAddress.protocol / localAddress.hostPort / path.elements).
withUid(path.uid)
new RemoteActorRef(transport, localAddress, rpath, supervisor, Some(props), Some(d))
} catch {
case NonFatal(e)
@ -280,15 +281,19 @@ private[akka] class RemoteActorRefProvider(
* Called in deserialization of incoming remote messages. In this case the correct local address is known, therefore
* this method is faster than the actorFor above.
*/
def actorForWithLocalAddress(ref: InternalActorRef, path: String, localAddress: Address): InternalActorRef = path match {
case ActorPathExtractor(address, elems)
if (hasAddress(address)) actorFor(rootGuardian, elems)
else new RemoteActorRef(transport, localAddress,
new RootActorPath(address) / elems, Nobody, props = None, deploy = None)
case _ local.actorFor(ref, path)
def actorForWithLocalAddress(ref: InternalActorRef, path: String, localAddress: Address): InternalActorRef = {
path match {
case ActorPathExtractor(address, elems)
if (hasAddress(address)) actorFor(rootGuardian, elems)
else new RemoteActorRef(transport, localAddress,
new RootActorPath(address) / elems, Nobody, props = None, deploy = None)
case _
local.actorFor(ref, path)
}
}
def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef = local.actorFor(ref, path)
def actorFor(ref: InternalActorRef, path: Iterable[String]): InternalActorRef =
local.actorFor(ref, path)
/**
* Using (checking out) actor on a specific node.
@ -297,7 +302,7 @@ private[akka] class RemoteActorRefProvider(
log.debug("[{}] Instantiating Remote Actor [{}]", rootPath, path)
// we dont wait for the ACK, because the remote end will process this command before any other message to the new actor
actorFor(RootActorPath(path.address) / "remote") ! DaemonMsgCreate(props, deploy, path.toString, supervisor)
actorFor(RootActorPath(path.address) / "remote") ! DaemonMsgCreate(props, deploy, path.toSerializationFormat, supervisor)
}
def getExternalAddressFor(addr: Address): Option[Address] = {