您可以将消息中的发件人参考传递给演员B,并将pipe
演员B的响应传递给self
。很显然,在它的响应演员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(...))
}
}
虽然上述方法是安全的,它会是简单的不使用ask
,如下图所示。如果您必须使用ask
,并且如果演员B在处理来自演员A的消息时处于阻塞状态,则请考虑按照here中所述配置单独的调度器。
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(...))
}
在这种情况下,在使用ask调用actor B后,在演员本身中进行回调是不好的? – Sidhant
@Sidhant:用'ask'使用'mapTo'和'pipeTo'(不是回调函数)是一种常见模式,正如[here]所述(http://doc.akka.io/docs/akka/2.5.4 /scala/actors.html#ask-send-and-receive-future)以及文档的其他部分。 – chunjef