我有两个演员电脑和打印机。计算机是打印机的父级,具有为打印机定义的一对一策略。
我列出了以下代码。
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
答案 0 :(得分:0)
将异常传递给您需要sender ! Status.Failure(e)
的发件人 - 其中e是例外
你可以直接从演员那里做到这一点,或者如果你想从主管那里做到这一点,你需要有一个异常的子类来保存发送者ref,以便主管能够发送异常回