私はあなたのコードサンプルで質問をもとに、ここで見ることができる質問のカップルがあります。
私はの定義におけるデフォルトのスーパーバイザーの動作を無効にするとき、私はどのようなものの種類を行うことができますが、例外を処理する方法は?
ask
を使用して、私は私が待っていますFuture
にFailure
結果を得るとき、私は物事の種類を行うことができますか?
まず最初の質問(通常は良いアイデア)で始まるのをしてみましょう。デフォルトのスーパバイザ戦略をオーバーライドすると、その子アクターで処理されなかった例外の種類を、その失敗した子アクターとの対処に関してどのように処理するかを変更することができます。前の文のキーワードはunhandled
です。リクエスト/レスポンスを行っているアクターにとって、実際には、特定の例外を処理(捕捉)して、特定のレスポンスタイプを返す(または上流の未来に失敗する、後でもっと失敗する)ことがあります。未処理の例外が発生した場合、基本的には送信者に問題の説明を返すことができなくなり、Future
が完了しないため、送信者はおそらくTimeoutException
になります。あなたが明示的に扱うものを理解したら、カスタムスーパーバイザ戦略を定義する際に、他のすべての例外を考慮することができます。ここでは、このブロック内:
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 10 seconds) {
case x: Exception => ???
}
あなたは障害が監督の立場からどのように処理するかを定義し、障害Directive
に例外タイプをマップするチャンスを得ます。オプションは次のとおりです。
ストップ - 完全子役を停止し、それに任意の複数のメッセージを送信しない
再開 - 失敗した子を再開し、
現在の内部状態を維持するためにそれを再起動しません
再起動 - 同様に再開するが、この場合には、古いインスタンスは破棄され、新しいインスタンスが作成され、内部状態がリセットされる(事前開始)
エスカレート - アップエスカレート今
OneForOneStrategy(maxNrOfRetries = 10, withinTimeRange = 10 seconds) {
case x: SQLException => Resume
case other => Restart
}
:スーパーバイザ
の親への連鎖は、それではSQLException
与えられたあなたが再開したいとあなたはあなたのコードは次のようになり、再起動したい他のすべて与えられたとしましょうFuture
がFailure
応答を返すときに何をすべきかに関する第2の質問については、この場合、それはその結果として起こるはずだったものに依存していると思います。Future
残りの俳優自体がHTTP要求を完了するための責任があったなら、あなたはこのような何かを行うことができ、(のはhttpCtxは、その上にcomplete(statusCode:Int, message:String)
機能を持っているとしましょう):
別の俳優が上流の完了を担当した今ならば
ask(dbActor, ReadCommand(reqCtx, id)).mapTo[SomeObject] onComplete {
case Success(obj) => reqCtx.complete(200, "All good!")
case Failure(err:TimeoutException) => reqCtx.complete(500, "Request timed out")
case Failure(ex) => reqCtx.complete(500, ex.getMessage)
}
HTTP要求し、その俳優に対応するために必要な、あなたはこのような何かを行うことができます:
val origin = sender
ask(dbActor, ReadCommand(reqCtx, id)).mapTo[SomeObject] onComplete {
case Success(obj) => origin ! someResponseObject
case Failure(ex) => origin ! Status.Failure(ex)
}
このアプローチは成功ブロックにあなたが最初に応答する前に、結果オブジェクトをマッサージすることを前提としています。あなたがそれを行うにはしたくないし、あなたが送信者に取り扱い、結果を延期したい場合は、あなただけ行うことができます。一つは、エラーのすべてをキャッチして転送することもできますシンプルなシステムについては
val origin = sender
val fut = ask(dbActor, ReadCommand(reqCtx, id))
fut pipeTo origin
私はそれを得ると思う、実際の鍵は未処理のものを理解することです – graph1ZzLle