试图取回 Actor 的响应时收到来自 Actor 的死信
getting dead letter from Actor when trying to get back the response from it
我有 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
的父 actor 结果
这是我得到的
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 和 return 它的结果(它的成功值或异常)
不要在 receive
中抛出异常,也不要在 sender
中关闭(sender
是一个函数,它只在 [=12= 的上下文中有效],您在 .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)
}
或者,更简单:
def receive: Receive {
case msg: InsertDataInMongo =>
mongoActor.forward(msg)
case msg: InsertDataInES =>
esActor.forward(msg)
}
我有 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
的父 actor 结果这是我得到的
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 和 return 它的结果(它的成功值或异常)
不要在 receive
中抛出异常,也不要在 sender
中关闭(sender
是一个函数,它只在 [=12= 的上下文中有效],您在 .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)
}
或者,更简单:
def receive: Receive {
case msg: InsertDataInMongo =>
mongoActor.forward(msg)
case msg: InsertDataInES =>
esActor.forward(msg)
}