Scala:有条件的演员链接

时间:2017-08-16 13:45:52

标签: scala akka future

我有两个演员A和B. Controller向actor A发送请求。现在,actor A返回类型为Try[AbcResponse]的响应。 AbcResponse在这里是一个案例类。 基于某些逻辑的Actor A可能直接返回此响应,或者它可能使用ask有条件地调用另一个actor B.在操纵B的响应后,它会将类型Try[AbcResponse]的响应发送到控制器。

那么我应该怎样做我的演员A来处理这种情况。我不想在我的演员A中等待,因为这会浪费线程池并导致系统速度减慢。我怎样才能有效地处理这个问题?

1 个答案:

答案 0 :(得分:0)

您可以将消息中的发件人引用传递给参与者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并且如果actor B处理来自actor 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(...))
}