【问题标题】:Actor selection演员选择
【发布时间】:2013-04-22 02:45:26
【问题描述】:

为什么当我使用 ActorContext 选择绝对路径时它不起作用(未正确选择演员并且没有收到 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 似乎应该可以工作。

【问题讨论】:

  • 请提供以下信息:1) Scala/Akka 版本 2) 显示actor1 是如何创建的代码 3) “不起作用”是什么意思?它编译吗?它会在运行时抛出异常吗? actor1 没有收到HelloResponse("hello back1") 消息吗?错误信息是什么意思?
  • 我添加了关于什么是不起作用的解释,感谢您的关注。

标签: scala akka


【解决方案1】:

【讨论】:

    【解决方案2】:

    当您在演员内部使用context.actorSelection 时,您的意思是在当前演员控制下(由/监督)找到一个演员。由于 actor1 可能不是由 actor2 启动(或者不受 actor2 监督),所以它不会解决任何问题。如果 actor1 实际上是由 actor2 拥有/启动的,那么您可能可以使用 context.actorSelection("/actor1") 来获取 actor2 的那个子演员。 context.system.actorSelection 起作用的原因是因为在开始搜索并完全限定到演员的路径之前,您首先要一直“向上”到 system。如果您以system.actorOf 启动它,则系统“拥有”actor1,因此使用该路径将允许您从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
    

    所以你可以看到我的系统中有两个Actor2 实例正在运行;一个直接从sys 生成,它绑定到/user/actor2,因为它是查找路径,一个从Actor1 的实例开始,绑定到/user/actor1/actor2 作为它的路径。

    演员系统是分层的,这个例子表明了这一点。 ActorSystem 本身就是一切的根源。选择参与者与 XPath 类似,因为您发出 select from 的上下文很重要。

    【讨论】:

      【解决方案3】:

      来自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")

      【讨论】:

      • 第一个 sn-p: context.actorSelection("/actor1") 也不起作用。如果正斜杠存在,ActorSelection 将从根监护人开始解析,正如 Roland 提到的那样。
      • 它可以工作,但是是一个错误,并且已经被修复。
      • 刚刚用 Akka 2.3-M2 测试过,context.actorSelection("/actor1") 不起作用。 ActorSelection 将在根监护人处开始解析。
      • 已在 2.1.4 中修复
      猜你喜欢
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-30
      • 1970-01-01
      相关资源
      最近更新 更多