如果子actor在重试N次后失败,主管是否有可能将异常传递给调用actor?

时间:2017-02-05 17:00:54

标签: scala akka

我有两个演员电脑和打印机。计算机是打印机的父级,具有为打印机定义的一对一策略。

我列出了以下代码。

class Computer extends Actor with ActorLogging{
  import Computer._
  import Printer._

  implicit val timeout: Timeout = 2 seconds

  val printer: ActorRef = context.actorOf(Props[Printer], "printer-actor")

  override def receive: Receive = {
    case Print(text) => {
      val printJob: Future[Any] = printer ? PrintJob(Random.nextInt, text)

      printJob.mapTo[Page].map {
        case Page(text) => {
          log.info(s"Received page containing text ${text}")
          context.system.shutdown()
        }
      }.onFailure {
        case t: Throwable => sender ! akka.actor.Status.Failure(t)
      }
    }
  }

  override val supervisorStrategy =
    OneForOneStrategy(maxNrOfRetries = 3, withinTimeRange = 1 minute) {
      case e : Exception => {
        log.info(s"caught exception of type ${e.getClass}")
        SupervisorStrategy.Restart
      }
    }
}

class Printer extends Actor with ActorLogging{
  import Printer._

  override def receive: Receive = {
    case PrintJob(id, text) => {
      log.info(s"Received ${PrintJob(id, text)}")
      if (Random.nextBoolean) sender ! Page(text)
      else throw new NoPaperException(id)
    }
  }


  override def preRestart(cause: Throwable, message: Option[Any]) = {
    log.info(s"Restarting actor ${self} because of ${cause}. Queueing message ${message}")
    postStop()
    message.map(self forward _)
  }
}

打印机根据随机生成器抛出异常。代码工作正常,主管重新启动并按照指示重试失败的子actor。

然而,如果所有试图让Printer actor工作失败的话,问题模式val printJob: Future[Any] = printer ? PrintJob(Random.nextInt, text)会因AkkaTimeoutException而失败。

有没有办法传回导致演员失败的确切异常?在这种情况下NoPapperException。

干杯,

UTSAV

1 个答案:

答案 0 :(得分:0)

将异常传递给您需要sender ! Status.Failure(e)的发件人 - 其中e是例外

你可以直接从演员那里做到这一点,或者如果你想从主管那里做到这一点,你需要有一个异常的子类来保存发送者ref,以便主管能够发送异常回