Akka主管抓住未来失败

时间:2014-12-18 00:36:12

标签: scala akka akka-supervision

我正在尝试使用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
      }

  }

我做错了什么?

非常感谢你们!

2 个答案:

答案 0 :(得分:4)

我遇到了同样的问题,Ryan的回答确实有所帮助。但是因为我是Akka的新手所以理解答案并不容易,所以我想提供一些细节。

首先,我认为onComplete根本不起作用。它只是注册回调函数,该函数可以在一个完全独立的线程中调用,而不会返回一个新的Future。因此,onComplete内引发的任何异常都将丢失。

相反,最好使用maprecoverrecoverWithtransform,因为它们会返回新的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,然后如果您希望由监督角色处理它,则重新抛出。