我正在尝试使用Futures和Akka主管开发应用程序,但是当A future将失败告诉演员时,其主管没有得到例外。
这是我的代码。
1)主管演员
class TransaccionActorSupervisor() extends Actor with ActorLogging {
val actor: ActorRef = context.actorOf(Props[TransaccionActor].withRouter(RoundRobinPool(nrOfInstances = 5)), "transaccion-actor")
def receive = {
case msg: Any => actor forward msg
}
override val supervisorStrategy = OneForOneStrategy() {
case exception =>
println("<<<<<<<<<<<<<<<<<<< IN SUPERVISOR >>>>>>>>>>>>>>>>>>>>>>>>>>>>")
Restart
}
}
监督演员
Class TransaccionActor() extends Actor with ActorLogging {
implicit val _: ExecutionContext = context.dispatcher
val transaccionAdapter = (new TransaccionComponentImpl with TransaccionRepositoryComponentImpl).adapter
def receive = {
case msg: GetTransaccionById =>
val currentSender: ActorRef = sender()
transaccionAdapter.searchTransaction(msg.id).onComplete {
case Success(transaction) => currentSender ! transaction
case Failure(error) => throw error
}
}
我做错了什么?
非常感谢你们!
答案 0 :(得分:4)
我遇到了同样的问题,Ryan的回答确实有所帮助。但是因为我是Akka的新手所以理解答案并不容易,所以我想提供一些细节。
首先,我认为onComplete
根本不起作用。它只是注册回调函数,该函数可以在一个完全独立的线程中调用,而不会返回一个新的Future
。因此,onComplete
内引发的任何异常都将丢失。
相反,最好使用map
,recover
,recoverWith
或transform
,因为它们会返回新的Future
。然后你需要将结果传递给一个演员,例如self
;接收方必须处理管道结果并重新抛出异常。
换句话说,你的受监督演员应该是这样的:
import akka.pattern.pipe
import akka.actor.Status.Failure
import akka.actor.Actor
class TransaccionActor() extends Actor with ActorLogging {
import context.dispatcher
val transaccionAdapter =
(new TransaccionComponentImpl with TransaccionRepositoryComponentImpl).adapter
def receive = {
case msg: GetTransaccionById =>
val currentSender: ActorRef = sender()
transaccionAdapter searchTransaction msg.id map { transaction =>
currentSender ! transaction
} pipeTo self
case Failure(throwable) => throw throwable
}
}
答案 1 :(得分:0)
演员未捕获演员未来的异常。您需要将异常传递给self
,然后如果您希望由监督角色处理它,则重新抛出。