[英]Scala: Conditional Actor Chaining
I have two actors A and B. A Controller sends a request to actor A. Now actor A return a response of type Try[AbcResponse]
. 我有两个演员A和B。一个控制器向演员A发送请求。现在,演员A返回
Try[AbcResponse]
类型的响应。 AbcResponse
being a case class here. AbcResponse
是这里的案例类。 Actor A based on some logic might directly return this response or it might conditionally call another actor B using ask. 基于某种逻辑的演员A可能会直接返回此响应,也可能会使用Ask有条件地调用另一个演员B。 After manipulating the response from B it would then send the response of type
Try[AbcResponse]
to the controller. 在处理了来自B的响应之后,它将把
Try[AbcResponse]
类型的响应发送到控制器。
So what should i do in my actor A to handle this situation. 所以我应该在演员A中做什么来处理这种情况。 I do not want to put a await in my actor A because that would waste the thread pool and cause slowdowns in the system.
我不想在演员A中等待,因为那样会浪费线程池并导致系统变慢。 How can i efficiently handle this?
我如何有效地处理呢?
You could pass the sender reference in a message to actor B and pipe
the response from actor B to self
. 你可以在一个消息传递发送者参照演员B和
pipe
从演员B向响应self
。 Obviously actor B in its response would have to pass this reference back to actor A. 显然,演员B在其响应中必须将此引用传递回演员A。
import akka.pattern.{ask, pipe}
case class MsgToActorB(..., target: ActorRef)
case class ResponseFromActorB(..., target: ActorRef)
class ActorA extends Actor {
def receive = {
case r: Request =>
val s = sender
implicit val timeout = Timeout(5 seconds)
// do something with the request
if (someCondition)
s ! Try(AbcResponse(...))
else
(actorB ? MsgToActorB(..., s)).mapTo[ResponseFromActorB].pipeTo(self)
case ResponseFromActorB(..., target) =>
// do something with the response from B and send a response to the original sender
target ! Try(AbcResponse(...))
}
}
While the above approach is safe, it'd be simpler to not use ask
as shown below. 尽管上述方法是安全的,但不使用
ask
会更简单,如下所示。 If you must use ask
and if actor B is blocking when it processes a message from actor A, then consider configuring a separate dispatcher as described here . 如果您必须使用
ask
,并且参与者B在处理来自参与者A的消息时是否阻塞,则可以考虑按此处所述配置单独的调度程序。
def receive = {
case r: Request =>
val s = sender
// do something with the request
if (someCondition)
s ! Try(AbcResponse(...))
else
actorB ! MsgToActorB(..., s)
case ResponseFromActorB(..., target) =>
// do something with the response from B and send a response to the original sender
target ! Try(AbcResponse(...))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.