从Akka的上下文中获取演员的最佳方法是什么?

时间:2015-10-28 17:46:07

标签: scala akka

我尝试了两种方法:

  • 使用Await.result

    Await.result(context.actorSelection(" akka:// Post / user / John").resolveOne(3秒),10秒)

    < / LI>
  • 手动获取未来价值

    context.actorSelection(&#34; akka:// Post / user / John&#34;).resolveOne(3秒).value.get.get

但我有这样的感觉我做错了什么。

我的演员代码:

def receive: Receive = {
  case "msg" ⇒ {

    ...

    val reader = Await.result(context.actorSelection("akka://Post/user/John").resolveOne(3 seconds), 10 seconds)
    reader ! data
  }
}

1 个答案:

答案 0 :(得分:2)

你应该永远不会阻止一个Actor的receive循环。最好浪费资源,更糟糕的是它可能导致死锁,因为线程池中的所有线程都已被使用,因此无法解决问题。

您最好的选择是:

直接将消息发送到actorSelection

您可以直接在演员选择上调用tell。当然,你不知道决议是否成功。如果这种情况发生了很多,那肯定不如让actorRef徘徊。

context.actorSelection("akka://Post/user/John").resolveOne(3 seconds) ! data

异步解析选择

鉴于您手上有Future,您可以在onComplete中发送消息或使用pipeTo将已解决的裁判发送给您自己:

发送解决方案

def receive = {
  case data:Data =>
    context.actorSelection("akka://Post/user/John").resolveOne(3 seconds)
      .onComplete {
         case Success(reader) => reader ! data
         case Failure(e) => // handle failure
      }
}

管道自我

case class Deferred(data: Data, ref: ActorRef)

var johnRef: Option[ActorRef] = None

def receive = {
  case data:Data => johnRef match {
    case Some(reader) => reader ! data
    case None => context.actorSelection("akka://Post/user/John")
      .resolveOne(3 seconds)
      .map( reader => Deferred(data,reader)
      .pipeTo(self)

  case Deferred(data,ref) =>
    johnRef = Some(ref)
    ref ! data
}