У меня есть контролирующий актор Akka, который использует маршрутизатор для пересылки сообщений рабочим акторам.
У меня есть класс, который обертывает супервизор, и когда я вызываю метод в этом классе, он «просит» супервизора что-то сделать, а затем я использую 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: кто регистрирует это исключение в консоли и как его остановить?