У меня есть наблюдательный аккорский аккор, который использует маршрутизатор для отправки сообщений рабочим актерам.Обработка исключений Akka 2.1 (Scala)
У меня есть класс, который обертывает супервизора, и когда я вызываю метод в этом классе, он «просит» супервизора что-то сделать, а затем я использую Await.result(theFuture)
для ожидания результата (я не могу продолжить без результата).
Если рабочие бросают исключение, я хочу перезапустить рабочего, который выбросил исключение, и я хочу, чтобы исключение было захвачено кодом, вызывающим класс-оболочку.
Я передал OneForOneStrategy
конструктору маршрутизатора, который возвращает RESTART
в случае Exception
. В методе postRestart
рабочего я регистрирую перезапуск, поэтому могу подтвердить, что рабочий фактически перезагружен.
Когда рабочий выдает исключение, он перезапускается, но исключение исчезает. Future
, который является результатом запроса супервизора, содержит исключение, но это akka.pattern.AskTimeoutException
, который вызывается через 5 секунд, а не 20 секунд, что является неявным таймаутом, который я задерживаю. Исключение фактически происходит менее секунды после начала работы.
Вопрос 1: Как я могу получить исключение от работника в коде, который вызывает мой класс оболочки?
Кроме того, способ приема работника, как это:
def receive = {
case r: Request =>
val response = ??? //throws an exception sometimes
sender ! response
}
Что-то регистрирует исключение на консоль, но это не мой код. Трассировка стека является:
[ERROR] [02/11/2013 21:34:20.093] [MySystem-akka.actor.default-dispatcher-9]
[akka://MySystem/user/MySupervisor/MyRouter/$a] Something went wrong!
at myApp.Worker.$$anonfun$receive$1.applyOrElse(Source.scala:169)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
at akka.actor.ActorCell.invoke(ActorCell.scala:386)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
at akka.dispatch.Mailbox.run(Mailbox.scala:212)
at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:502)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)
Линия 169 из Source.scala
является линия val response = ???
показано в листинг receive
выше способом.
Вопрос 2:, который регистрирует это исключение для консоли и как его остановить?
Q2: см. ActorLogging. – twillouer
Q1: почему бы не использовать Try? (scala 2.10) – twillouer
@twillouer Я использую Try -> myFuture.value.get дает Try, который в этом случае является ошибкой, содержащей исключение таймаута. –