目前在现有的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
的使用感到有点困惑,因为这在当前线程中是阻塞的。我可以使用哪种替代方案?
答案 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
可能会失败,因此您可能也想要考虑该方案。