如何让一个演员在另一个演员中非封锁?

时间:2018-04-26 12:45:57

标签: scala akka akka-http

目前在现有的scala akka-http项目中,我们有一群需要告诉其他演员消息的演员。

在演员中,我们将通过以下方式获得演员的参考:

class OurActor extends Actor {
     private implicit val timeout: Timeout = 15.seconds
     private val otherActor: ActorRef = Await.result[ActorRef](context.system.actorSelection("path/to/other/actor").resolveOne()(timeout), 15.seconds)

       override def receive: Receive = {
    case SomeMessage => {
      ...
      dataSets.foreach(_.foreach(otherActor ! _))
    }
  }
}

我对Await.result的使用感到有点困惑,因为这在当前线程中是阻塞的。我可以使用哪种替代方案?

3 个答案:

答案 0 :(得分:2)

您可以将另一个actor注入OurActor

的构造函数参数
object OurActor {
  def props(otherActorRef: ActorRef) = Props(classOf[OurActor],otherActorRef)
}


class OurActor(otherActor: ActorRef) extends Actor {
     private implicit val timeout: Timeout = 15.seconds

       override def receive: Receive = {
    case SomeMessage => {
      ...
      otherActor ! _
    }
  }
}

当你实例化你的演员时:

val otherActor = actorSystem.actorOf(OtherActor.props, "otherActor")
val ourActor   = actorSystem.actorOf(OurActor.props(otherActor) "ourActor")

答案 1 :(得分:1)

你不一定需要一个actorRef,但你也可以直接使用选择器向一个actor(或多个actor)发送消息:

class MetronomeJobAlertActor extends Actor {
  private implicit val materializer: ActorMaterializer = ActorMaterializer(ActorMaterializerSettings(context.system))
  private implicit val ec = context.dispatcher
  private implicit val sys = context.system
  private val otherActorSelection: ActorSelection = context.system.actorSelection("path/to/other/actor")

  override def receive: Receive = {
    case SomeMessage => {
      ...
      dataSets.foreach(otherActorSelection ! _))
  }
}

答案 2 :(得分:1)

如果您想确保它是可解析的,也许您可​​以直接在Future内执行class OurActor extends Actor { override def receive: Receive = { case SomeMessage => { ... context.system.actorSelection("path/to/other/actor").resolveOne().map { actorRef => dataSets.foreach(_.foreach(actorRef ! _)) } } } } 。像这样:

dataSets.foreach

这意味着dataSets语句将异步发生。如果Future是可变的,您将需要小心,因为事情将在不同的线程中运行。此外,approx_equal可能会失败,因此您可能也想要考虑该方案。