Scala 在阿克卡,从上下文中获得演员的最佳方式是什么?

Scala 在阿克卡,从上下文中获得演员的最佳方式是什么?,scala,akka,Scala,Akka,我尝试了两种方法: 使用wait.result wait.result(context.actorSelection(“akka://Post/user/John)。解析1(3秒),10秒) 手动获取未来值 context.actorSelection(“akka://Post/user/John)。解析一(3秒)。value.get.get 但我觉得我做错了什么 我的演员代码: def receive: Receive = { case "msg" ⇒ { ...

我尝试了两种方法:

  • 使用
    wait.result

    wait.result(context.actorSelection(“akka://Post/user/John)。解析1(3秒),10秒)

  • 手动获取未来值

    context.actorSelection(“akka://Post/user/John)。解析一(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
  }
}

您应该永远不要在参与者的
接收
循环中阻塞。在最好的情况下,它会浪费资源,在更坏的情况下,它会导致死锁,因为线程池中的所有线程都已在使用,因此无法进行解决

您的最佳选择是:

将消息直接发送到actorSelection

您可以直接在演员选择上调用
tell
。当然,你不知道解决方案是否成功。如果这种情况经常发生,那肯定比让actorRef闲逛效率低

context.actorSelection("akka://Post/user/John").resolveOne(3 seconds) ! data
异步解析所选内容

鉴于您手中有一个
未来
,您可以在
onComplete
中发送您的信息,或者使用
pipeTo
将解析的ref发送回您自己:

决议后发送

自吹自擂


谢谢很好的解释!还有一个建议:我为johnRef使用了一个
var
,但是如果你打算继续改变actor状态,请阅读
been
,以允许以不变的方式更改actor状态
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
}