演员选择

时间:2013-04-28 09:49:45

标签: scala akka

为什么当我选择一个带有ActorContext的绝对路径时,它不起作用(未正确选择actor并且没有收到HelloResponse消息)?

//From Actor2:
//This doesn't work (Message never received)
context.actorSelection("/user/actor1") ! HelloResponse("hello back1")
//This works (actor 1 receives the message)
context.system.actorSelection("/user/actor1") ! HelloResponse("hello back2")

我是Scala / Akka的新手,但reading documentation似乎应该有效。

3 个答案:

答案 0 :(得分:4)

答案 1 :(得分:2)

当你在演员中使用context.actorSelection时,你所说的是在当前演员控制下找到一个演员(由/监督开始)。由于actor1可能不是由actor2启动的(或者不是由actor2监督的),因此它不会解析为任何东西。如果actor1实际上由actor2拥有/启动,那么你可能会context.actorSelection("/actor1")来获得actor2的子actor。 context.system.actorSelection之所以有效,是因为在开始搜索之前,你首先要“向上”到system并完全限定演员的路径。系统“拥有”actor1如果你以system.actorOf启动它,那么使用该路径将允许你从system开始到达它。

显示我的意思的一些代码:

class Actor1 extends Actor{
  override def preStart = {
    context.actorOf(Props[Actor2], "actor2")
  }
  def receive = {
    case _ =>
  }
}

class Actor2 extends Actor{
  override def preStart = {println("my path is: " + context.self.path)}
  def receive = {
    case _ =>
  }
}

object FutureTesting {
  def main(args: Array[String]) {
    val sys = ActorSystem("test")
    implicit val ec = sys.dispatcher

    //Starting an Actor2 from system
    sys.actorOf(Props[Actor2], "actor2")

    //Starting an Actor1 from system which in turn starts an Actor2
    sys.actorOf(Props[Actor1], "actor1")
  }
}

运行此示例时,您将看到:

my path is: akka://test/user/actor1/actor2
my path is: akka://test/user/actor2

所以你可以看到我在我的系统中运行了2个Actor2个实例;一个直接来自sys的{​​{1}}与/user/actor2相关联,因为它是查找路径,另一个是从Actor1的{​​{1}}实例开始,其路径为/user/actor1/actor2

演员系统是分层的,这个例子表明了这一点。 ActorSystem本身就是一切的根源。因此,选择actor类似于XPath,因为您要从事务中发出select。

答案 2 :(得分:1)

actor2开始,您需要使用

context.actorSelection("/actor1")

我同意它不直观,因为隐喻是一个文件系统,当使用文件系统时,前导/是一个绝对路径,意味着从根开始。它也与actorFor不一致,因为

context.actorFor("/user/actor1")

返回顶级Actor1(请参阅Absolute and Relative Paths

编辑 - 这是一个在Akka 2.1.4中修复的错误(参见Roland的回答)。从2.1.4开始,您可以使用context.actorSelection("/user/actor1")