diff --git a/akka-remote/src/main/scala/akka/remote/Remote.scala b/akka-remote/src/main/scala/akka/remote/Remote.scala index 65bcf3167d..092dbd8bb6 100644 --- a/akka-remote/src/main/scala/akka/remote/Remote.scala +++ b/akka-remote/src/main/scala/akka/remote/Remote.scala @@ -260,11 +260,11 @@ class RemoteMessage(input: RemoteMessageProtocol, remote: RemoteSupport, classLo if (input.hasSender) provider.actorFor(provider.rootGuardian, input.getSender.getPath) else remote.system.deadLetters - lazy val recipient: InternalActorRef = provider.actorFor(provider.rootGuardian, input.getRecipient.getPath) + lazy val recipient: InternalActorRef = provider.actorFor(provider.rootGuardian, originalReceiver) lazy val payload: AnyRef = MessageSerializer.deserialize(remote.system, input.getMessage, classLoader) - override def toString = "RemoteMessage: " + payload + " to " + recipient + " from " + sender + override def toString = "RemoteMessage: " + payload + " to " + recipient + "<+{" + originalReceiver + "} from " + sender } trait RemoteMarshallingOps { diff --git a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala index e77aab054e..df7fcf8544 100644 --- a/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala +++ b/akka-remote/src/main/scala/akka/remote/RemoteActorRefProvider.scala @@ -75,7 +75,18 @@ class RemoteActorRefProvider( else { val path = supervisor.path / name - deployer.lookupDeploymentFor(path.elements.mkString("/", "/", "")) match { + val deployment = deployer.lookupDeploymentFor(path.elements.mkString("/", "/", "")) + + @scala.annotation.tailrec + def lookupRemotes(p: Iterable[String]): Option[DeploymentConfig.Deploy] = { + p.headOption match { + case None ⇒ None + case Some("remote") ⇒ lookupRemotes(p.drop(2)) + case Some(_) ⇒ deployer.lookupDeploymentFor(p.mkString("/", "/", "")) + } + } + + deployment orElse (if (path.elements.head == "remote") lookupRemotes(path.elements) else None) match { case Some(DeploymentConfig.Deploy(_, _, routerType, nrOfInstances, RemoteDeploymentConfig.RemoteScope(remoteAddresses))) ⇒ // FIXME RK deployer shall only concern itself with placement of actors on remote nodes @@ -249,7 +260,12 @@ private[akka] class RemoteActorRef private[akka] ( extends InternalActorRef { def getChild(name: Iterator[String]): InternalActorRef = { - new RemoteActorRef(provider, remote, path / name.toStream, Nobody, loader) + val s = name.toStream + s.headOption match { + case None ⇒ this + case Some("..") ⇒ getParent getChild name + case _ ⇒ new RemoteActorRef(provider, remote, path / s, Nobody, loader) + } } @volatile diff --git a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala index 3d79cebef9..7d0676464f 100644 --- a/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala +++ b/akka-remote/src/test/scala/akka/remote/RemoteCommunicationSpec.scala @@ -12,7 +12,7 @@ object RemoteCommunicationSpec { var target: ActorRef = context.system.deadLetters def receive = { - case (p: Props, n: String) ⇒ context.actorOf[Echo]("grandchild") + case (p: Props, n: String) ⇒ sender ! context.actorOf[Echo](n) case ex: Exception ⇒ throw ex case s: String ⇒ sender ! context.actorFor(s) case x ⇒ target = sender; sender ! x @@ -33,7 +33,6 @@ class RemoteCommunicationSpec extends AkkaSpec(""" akka { actor.provider = "akka.remote.RemoteActorRefProvider" cluster.nodename = Nonsense - loglevel = DEBUG remote.server { hostname = localhost port = 12345 @@ -51,9 +50,6 @@ akka { val conf = ConfigFactory.parseString("akka.remote.server.port=12346").withFallback(system.settings.config) val other = ActorSystem("remote_sys", conf) - system.eventStream.subscribe(system.actorFor("/system/log1-TestEventListener"), classOf[RemoteLifeCycleEvent]) - other.eventStream.subscribe(other.actorFor("/system/log1-TestEventListener"), classOf[RemoteLifeCycleEvent]) - val remote = other.actorOf(Props(new Actor { def receive = { case "ping" ⇒ sender ! (("pong", sender)) @@ -111,7 +107,7 @@ akka { expectMsg("postStop") } - "look-up actors across node boundaries" ignore { + "look-up actors across node boundaries" in { val l = system.actorOf(Props(new Actor { def receive = { case (p: Props, n: String) ⇒ sender ! context.actorOf(p, n) @@ -121,12 +117,13 @@ akka { l ! (Props[Echo], "child") val r = expectMsgType[ActorRef] r ! (Props[Echo], "grandchild") + val remref = expectMsgType[ActorRef] + remref.isInstanceOf[LocalActorRef] must be(true) val myref = system.actorFor(system / "looker" / "child" / "grandchild") myref.isInstanceOf[RemoteActorRef] must be(true) myref ! 43 expectMsg(43) - val remref = lastSender - remref.isInstanceOf[LocalActorRef] must be(true) + lastSender must be theSameInstanceAs remref (l ? "child/..").as[ActorRef].get must be theSameInstanceAs l (system.actorFor(system / "looker" / "child") ? "..").as[ActorRef].get must be theSameInstanceAs l }