問題タブ [error-kernel]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scala - Akka アクターでの障害の処理
SimpleActor
メッセージを自分自身に送信することで定期的なタスクを実行するActor ( ) がある非常に単純な例があります。メッセージは、アクターのコンストラクターでスケジュールされます。通常の場合 (つまり、障害がない場合)、すべて正常に動作します。
しかし、アクターが障害に対処しなければならない場合はどうでしょう。別のアクター ( SimpleActorWithFault
) がいます。このアクターには欠点がある可能性があります。この場合、例外をスローして自分で生成しています。障害が発生すると (つまり、SimpleActorWithFault
例外がスローされると)、自動的に再起動されます。ただし、この再起動により、アクタ内のスケジューラが台無しになり、例外として機能しなくなります。また、障害が急速に発生すると、予期しない動作がさらに発生します。
私の質問は、そのような場合に障害に対処するための好ましい方法は何ですか? Try
ブロックを使用して例外を処理できることを知っています。しかし、Try をスーパー クラスに配置できない別のアクターを拡張している場合や、例外的な障害がアクターで発生した場合はどうなるでしょうか。
scala - Akka のエラー カーネルと監視: 古い子からのメッセージは再起動されたアクターに配信されますか?
私はベスト プラクティスに従い、Akka でエラー カーネル パターンを適用しようとしています。ここからのこの引用によると:
1 つのアクターが非常に重要なデータを運ぶ場合 (つまり、回避可能であればその状態が失われてはならない)、このアクターは、監督する子に潜在的に危険なサブタスクを供給し、これらの子の失敗を適切に処理する必要があります。要求の性質によっては、要求ごとに新しい子を作成するのが最善の場合があります。これにより、応答を収集するための状態管理が簡素化されます。これは、Erlang の「エラー カーネル パターン」として知られています。
... 子を作成し、エラーが発生しやすい作業を子に委任して、重要な状態を親/スーパーバイザー アクターに集中させることをお勧めします。
このシナリオで、重要な状態のアクターが何らかの理由で再起動された場合、その古い子 (再起動前に作成されたもの) からのメッセージを処理する必要がありますか?
これを例で説明しましょう。
アクターが 3 人いると仮定しましょう: A
(の親/スーパーバイザーB
)、B
(の親/スーパーバイザーC
、重要な状態を含む)、およびC
.
A
の監視戦略は、例外が発生した場合にその子を再起動するように構成されています。
C
B
のコンストラクタで作成されます。
次に、メッセージbc
がフォームB
から に送信されたとしますC
。C
処理を開始し (そこで長時間実行される計算を実行すると想像してください)、処理が完了すると、 に応答B
しcb
ます。
ここで、 before が に送信され、 send メッセージcb
によって処理されたと仮定します。このメッセージによって例外がスローされ、の監視戦略の決定が再開されます。B
A
ab
B
B
A
B
の子としての再起動B
C
中に停止しますB
( のコンストラクターで newC'
が作成されますB
)。
再起動する前に送信されたものからB
受信を再起動しますか?cb
C
B
はいの場合、sender
of cb
( C
) は restarted の子と見なされB
ますか? アクターの ref のC
とは等しいでしょうか (との名前が等しいとC'
仮定します)?C
C'
akka - さまざまなタイプのアクターに対する Akka スーパーバイザー戦略
私は Akka を使用しており、ユーザー ガーディアン アクターの独自の監督戦略を定義したいと考えています。TaskActor と MessageActor という 2 種類のアクターを定義しました。それらはトップレベルのアクターとしてインスタンス化されます。ユーザー ガーディアンに次の監視戦略を適用してほしいと思います: TaskActor を停止し、MessageActor が例外をスローしたときに再開します (スローされる例外の特定のタイプは気にしません)。どうすればいいですか?
multithreading - 実際にアクターを使用する場所と方法
複雑なバックエンド サービスでアクターをどのように使用できるか最終結果を計算するまで、応答などに基づいて続行しますか?
このようなサービスを実装するためにアクターを使用しようとすると、このワークフローのどの部分をアクターによって実装する必要があり、どの部分を実装すべきでないのかという疑問が生じます。
アクター インスタンスは、達成しようとしているタスクが完了するまで使用しているスレッドを解放しません (Future に委譲しない限り)。 N 層の子は、アクターの概念に基づく理想的な設計ですが、一方では最大 N-1 スレッド (最初の要求ごと) を保持します。完了する階層内のアクター。具体的には、階層の最上位のアクターはほとんどの時間アイドル状態になります。
この階層設計は、エラー カーネルパターンにも一致します。
しかし、これは並行性にとって非常に悪いように思えます。
そして、このアクターの階層を維持しようとしても、Future で各アクターへの呼び出しをラップする (伝えるのではなく、子アクターに尋ねることによって) 場合でも、ロックははるかに短くなります (まだ存在しますが) - それでも機能します。非常に多くの Future を使用すると、ステートフルなアクター、またはシステムの状態を自分自身で同期されない方法で変更するアクター (つまり、データベースを変更するだけではなく、少なくとも単純な要求の場合、データベースを介して自動的に行われる) と連携することができなくなります。トランザクションではなく、アプリケーション内の一部のグローバル変数を変更します)。
では、アクターはワークフローの下位レベルでのみ使用する必要がありますか?
または、大部分が階層的である (そしてほとんどがそうである) ワークフローをよりシリアルな方法で書き直す必要があるため、それほど多くのレベルの子アクターは必要ありません (しかし、それは非常に難しく、不自然であり、実装フレームワークも提供するように思われます)。デザインに大きな影響を与えます)。
つまり、アクターは非常に限られていること、耐障害性は主に従来の例外処理によって処理する必要があること、いずれにせよ、耐障害性アプリケーションを必要としても、アプリケーションの設計にそれほど影響を与えるべきではないことを認識していることを意味します。応用。その場合、なぜ役者を悩ませるのですか?複雑なスパゲッティのようなメッセージの結び目のワークフローを理解するためにすべてのアクターの実装を読み取る必要があるフレームワークで作業することは、階層構造に基づくフレームワークで作業するよりもはるかに簡単ではありません。必ずしも実装を覗き込むことなく、メソッドのシグネチャを調べます。
簡単なスケールアウトなど、アクターの利点の多くは、アクターによってアプリケーションのごく一部しか実装されていない場合、関連性が低く実用的ではないように思われます。