Akka 2.1异常处理(Scala)

Akka 2.1异常处理(Scala),scala,akka,actor,akka-supervision,Scala,Akka,Actor,Akka Supervision,我有一个监督Akka演员,它使用路由器将消息转发给工人演员 我有一个类包装了主管,当我调用该类上的方法时,它“要求”主管做一些事情,然后我使用wait.result(theFuture)等待结果(没有结果我无法继续) 如果worker抛出异常,我希望重新启动抛出异常的worker,并希望调用包装器类的代码捕获异常 我将一个OneForOneStrategy传递给路由器构造函数,如果出现异常,它将返回RESTART。在worker的postreast方法中,我记录了重启过程,以便验证worker是

我有一个监督Akka演员,它使用路由器将消息转发给工人演员

我有一个类包装了主管,当我调用该类上的方法时,它“要求”主管做一些事情,然后我使用
wait.result(theFuture)
等待结果(没有结果我无法继续)

如果worker抛出异常,我希望重新启动抛出异常的worker,并希望调用包装器类的代码捕获异常

我将一个
OneForOneStrategy
传递给路由器构造函数,如果出现
异常
,它将返回
RESTART
。在worker的
postreast
方法中,我记录了重启过程,以便验证worker是否实际重启

当工作进程抛出异常时,它会重新启动,但异常会消失。询问主管后得到的
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)
Source.scala
的第169行是上面
receive
方法列表中显示的
val response=???


问题2:谁正在将该异常记录到控制台,我如何停止它?

为了通知您的一个孩子失败,您需要

  • 首先,观察孩子
  • 然后,当参与者死亡时,将向您发送一个
    终止()
    ,并对其进行引用
比如:

class ParentActor extends Actor {
   // this is sample of how to watch for death of one of your children 
   val childActor = context.actorOf(Props[SomeService], "SomeService")
   val dyingChild = context.watch(context.actorOf(childActor))

   def receive = {
     case Terminated(`dyingChild`) =>
        println("dyingChild died") 
     case Terminated(terminatedActor) => 
        println(s"This child just died $terminatedActor")
   }
 }
希望这有帮助。

1)

“告诉失败”会导致调用方获得包含异常的失败。抛出“e”会导致调用oneForOneStrategy,从而重新启动工作进程

(二)

记录故障的是参与者系统本身,也是唯一的方法 让它安静下来就是通过创建和配置来过滤掉一些东西 您自己的LoggingAdapter,如下所述 有一个 换这张票 但它是有针对性的 对于Akka 2.2


回答:Q2:参见ActorLogging.Q1:为什么不使用Try?(scala 2.10)@twillouer我正在使用Try->myFuture.value.get进行尝试,在本例中,这是一个包含超时异常的失败。为什么不返回一次尝试?像发送者一样!Try(…)?您的意思是捕获工作进程中的异常并返回失败?如果这就是你的意思,那么我希望尽可能避免在工人中发现异常。这两个问题都没有答案。
try somethingThatCanFail() catch {
    case e: Exception => sender ! Status.Failure(e); throw e
}