如果子角色在重试 N 次后失败,主管是否可以将异常传递给调用执行组件



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

我在下面列出了代码。

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工作的尝试都失败,则询问模式val printJob: Future[Any] = printer ? PrintJob(Random.nextInt, text)失败并显示AkkaTimeoutException。

有没有办法传回导致演员失败的确切异常?在本例中为 NoPapperException。

干杯

乌察夫

要将异常传递回发送方,您需要sender ! Status.Failure(e) - 其中 e 是异常

你可以直接从执行组件执行此操作,或者如果你想从主管那里执行此操作,你需要有一个异常子类来保存发送方引用,以便主管能够将异常发回

最新更新