我有两个演员电脑和打印机。计算机是打印机的父级,并且具有为打印机定义的一对一策略。
我在下面列出了代码。
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 是异常
你可以直接从执行组件执行此操作,或者如果你想从主管那里执行此操作,你需要有一个异常子类来保存发送方引用,以便主管能够将异常发回