2

context.parent我来说,参考没有这样做。在 Play 项目中,我启动了一个新的 Actor 来处理每个传入的请求:

val myActor: ActorRef = system.actorOf(Props(classOf[MyActor])

val future: Future[String] = (myActor ? Hello)(5.seconds).mapTo[String]

future.map(result => Ok(result)).recover {
  case ex: AskTimeoutException => Ok("timeout expired")
  case _ => Ok("error")
}

这会在 : 的接收方法中触发更多的actor消息传递myActor:当anotherActor响应 时,后者会向其父级myActor发送消息。AllGood

class MyActor extends Actor {

  // other stuff, among which setup of anotherActor

  def receive: Actor.Receive = {
    case Hallo => anotherActor ! Hello
    case HelloBack => context.parent ! AllGood
  }
}  

class AnotherActor extends Actor {
  def receive: Actor.Receive = {
    case Hallo => sender ! HelloBack
  }
}

一切正常,直到myActor尝试向context.parent. 我deadLetters在控制台中收到一条消息。

from Actor[xyz] to Actor[akka://my-system/user] was not delivered. [1] dead letters encountered.

myActor如果保留对 original 的引用,我可以使它工作sender,并且代码看起来像这样:

class MyActor extends Actor {

  var myDad: Option[ActorRef] = None  // <--- NEW REFERENCE

  // other stuff, among which setup of anotherActor

  def receive: Actor.Receive = {
    case Hallo => {
      myDad = Some(sender)
      anotherActor ! Hello
    }
    case HelloBack => myDad ! AllGood   <-- MYDAD INSTEAD OF CONTEXT.PARENT
  }
}  

class AnotherActor extends Actor {
  def receive: Actor.Receive = {
    case Hallo => sender ! HelloBack
  }
}

引用myDad实际上类似于Actor[akka://my-system/temp/$a],而我希望它与context.parentwhich was相同Actor[akka://my-system/user]。不是同一个演员吗?

任何人都可以向我解释这种行为,并提出一种更清洁的方法来解决这个问题吗?谢谢。

4

1 回答 1

2

看起来你混淆了父母和发件人的概念。

  1. context.parent [akka://my-system/user] 是正常的,因为 actor 是使用system.actorOf(Props(classOf[MyActor]).

  2. sender 方法将返回发送消息的参与者。这里重要的是;这不是将消息发送给您的演员的演员系统。当使用询问模式时,Akka 会创建一个临时演员(在您的情况下Actor[akka://my-system/temp/$a]),它将发送消息并等待答案。当收到响应时,Future 完成。

如果您愿意,可以转发原始发件人,以便您AnotherActor可以直接回复 HelloBack 到由询问模式创建的临时演员。

为此,只需更改消息传递给 anotherActor 的方式。

def receive: Actor.Receive = {
case Hallo => anotherActor.tell(Hello, sender)
}
于 2013-11-14T09:05:00.383 回答