尝试从Actor获得响应时收到来自Actor的死信

时间:2019-02-19 12:40:34

标签: scala akka future

我有ParentActor和2个ChildActor,这是我的代码

Class ParentActor extends Actor {

val mongoActor = context.of.....
val esActor = context.of ............

def receive {
case InserInMongo(obj) =>
val mFuture = ask(mongoActor, InsertDataInMongo(object)).mapTo[Boolean]
      mFuture.onComplete {
        case Success(resultMongo) =>
             sender ! resultMongo
        case Failure(e) =>
            sender ! akka.actor.Status.Failure(e)
            throw e
        }   

case InserInES(obj) =>
val eFuture = ask(esActor, InsertDataInES(object)).mapTo[Boolean]
      eFuture.onComplete {
        case Success(resultES) =>
             sender ! resultES
        case Failure(e) =>
            sender ! akka.actor.Status.Failure(e)
            throw e
        }
}
}

这是呼叫代码

class Demo {
    val mongoFuture = ask(parentActor, InsertInMongo(obj))
            .mapTo[Boolean]
            .recover {
              case e =>
                println("error in mongo: " + e)
                false
            }

          val esFuture = ask(parentActor, InsertInES(obj))
            .mapTo[Boolean]
            .recover {
              case e =>
                println("error in ES: " + e)
                false
            }

          val f = Future.sequence(List(mongoFuture, esFuture))
          val result: Seq[Boolean] = Await.result(f, Duration.Inf)
          log.info ("result {}",result)
}

一切正常,但是如果我在mongoChildActor中遇到了MongoException,我将无法获得ES的父演员结果

这就是我要得到的

17:19:45.782 [MyActorSystem-akka.actor.default-dispatcher-4] INFO  akka.actor.DeadLetterActorRef - Message [java.lang.Boolean] from Actor[akka://MyActorSystem/user/ParentActor#1383701267] to Actor[akka://MyActorSystem/deadLetters] was not delivered. [2] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

我想要的是,如果我在mongo中遇到异常,则得到异常,然后应继续执行ES并返回其结果(成功值或异常)

1 个答案:

答案 0 :(得分:3)

请勿在{{1​​}}中引发异常,也不要关闭receivesender是一个函数,仅在sender的上下文中有效,您正在receive内的另一个线程上使用它)。

这样的事情应该做你想要的:

.onComplete

或者,甚至更容易:

 import akka.pattern.pipe
 def receive: Receive = {
   case InserInMongo(obj) =>
     ask(mongoActor, InsertDataInMongo(object)).pipeTo(sender)   

  case InserInES(obj) =>
     ask(esActor, InsertDataInES(object)).pipeTo(sender)

 }