2

ルーターを使用してメッセージをワーカーアクターに転送する監視Akkaアクターがいます。

スーパーバイザーをラップするクラスがあり、そのクラスのメソッドを呼び出すと、スーパーバイザーに何かをするように「要求」しAwait.result(theFuture)、結果を待つために使用します(結果なしでは続行できません)。

ワーカーが例外をスローした場合、例外をスローしたワーカーを再起動し、ラッパークラスを呼び出すコードによって例外がキャッチされるようにします。

をルーターコンストラクターに渡しました。ルーターコンストラクターは、の場合にOneForOneStrategy返されます。ワーカーの方法では、再起動をログに記録するので、ワーカーが実際に再起動されたことを検証できます。RESTARTExceptionpostRestart

ワーカーが例外をスローすると、ワーカーは再起動されますが、例外は消えます。Futureスーパーバイザーに問い合わせた結果であるこれには例外が含まれていますが、akka.pattern.AskTimeoutExceptionこれは20秒ではなく、わずか5秒後にスローされます。これは、私が残している暗黙のタイムアウトです。例外は、実際にはワーカーの起動後1秒以内に発生します。

質問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:誰がその例外をコンソールに記録していますか?どうすればそれを止めることができますか?

4

2 に答える 2

3

1)

try somethingThatCanFail() catch {
    case e: Exception => sender ! Status.Failure(e); throw e
}

「tell failure」により、呼び出し元は例外を含む Failure を取得します。「e」をスローすると、ワーカーを再起動する oneForOneStrategy が呼び出されます。

2)

障害をログに記録するのはアクター システム自体であり、それを沈静化する唯一の方法は、http://doc.akka.io/docs/akka/2.1 で説明されているように、独自の LoggingAdapter を作成して構成することにより、物事を除外すること です。 0/scala/logging.html https://www.assembla.com/spaces/akka/tickets/2824を変更するためのチケットがあり ますが、Akka 2.2 を対象としています。

https://groups.google.com/forum/#!topic/akka-user/fenCvYu3HYEで回答

于 2013-02-15T18:08:56.357 に答える
0

お子様の 1 人が失敗したことを通知するには、次のことを行う必要があります。

  • まずはwatch子供
  • Terminated()次に、アクターが死亡したときに、それへの参照とともにが送信されます。

何かのようなもの:

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")
   }
 }

お役に立てれば。

于 2013-02-14T01:25:20.793 に答える