Akka 2.1异常处理(Scala)
我有一个监督Akka演员,它使用路由器将消息转发给工人演员 我有一个类包装了主管,当我调用该类上的方法时,它“要求”主管做一些事情,然后我使用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是
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
}