問題タブ [erlang-supervisor]
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.
erlang - スーパーバイザーの子が start_link からエラーを返したときに、エラーの理由を常にログに記録/表示するにはどうすればよいですか?
gen_server
スーパーバイザー (それ自体はアプリケーションによって開始されます) から を開始する場合、gen_server の が返されない場合に問題が発生start_link
します{ok, ...}
が{error, Reason}
、表示される唯一のエラー メッセージは次のとおりです。
終了するためのReason
ものは表示/ログに記録されません。
これらのエラーがスーパーバイザーに返されるのを確認/記録する方法はありますか?
私が使用している子仕様は、例えば次のとおりです。
編集:明確化
私は error_logger について知っており、すでに使用しています。問題は、何かをログに記録する方法ではなく、スーパーバイザーに終了の理由をログに記録させる方法です。たとえば、誰がエラーを返し、何が返されたかをログに記録します。
そして、これも邪魔にならないようにするために、はい、私は sasl をオンにして erlang を開始します:
erlang - スーパーバイザーは独自のスーパーバイザーを開始する必要がありますか?
start_child
スーパーバイザーが 1 人いて、このスーパーバイザーに対していくつか実行する必要があるとします。最初にすべてのスーパーバイザーを起動する必要がありますか? supervisor:start_child(my_sup,[])
または、my_sup を開始せずにのみできますか?
erlang - Erlang: Supervisor(3)、子プロセスの追加
simple_one_for_one
動的な子プロセスを既存のスーパーバイザーに追加する方法 (再起動戦略)の例はどこにありますか?
erlang - Erlang 動的スーパーバイザーは gen_server を開始します
他のスーパーバイザーを作成するルート スーパーバイザーがあります。
そして、gen_server - リスナーがあります。スーパーバイザーが作成されたときに、この gen_server をpopd_listener_sup
スーパーバイザーで実行するにはどうすればよいですか?
ありがとうございました。
erlang - 動的スーパーバイザーで終了した子の仕様を原子的に削除する方法
この質問には USB の知識は必要ありません。例をより具体的にするために説明しただけです。
USB バス上の特定のデバイスに動的スーパーバイザを実装しようとしています。これらのデバイスにはアドレスがあり、システムの存続期間中に現れたり消えたりします。
デバイスごとに、スーパーバイザーの動的な子が必要です。
これらの子は一時的なものであるため、いったんクラッシュまたは終了すると、再起動しません (おそらくその時点でなくなっているため)。
特定の時間に USB ポートをスキャンし、処理したい USB デバイスのすべてのアドレスのリストを生成するプロセスがあります。
supervisor:which_children/1
各スキャンの前に呼び出して、存在するが子プロセスが実行されていないデバイスを見つける予定です。
実行中の子を持つアドレスを見つけるために、アドレスを含む childspec の Id アトムを作成する予定です (可能なアドレスはわずかしかありません)。たとえば adr_12
、子が address を処理する場合12
です。
行方不明の子を開始/再起動しようとすると、一時的な子が終了またはクラッシュしたときに子仕様が自動的に削除されないというやや醜い状況があります (少なくともそうであると思います)。したがって、次のようなコードが必要になります。
supervisor:which_children/1
次に、すでに終了した子供も返すかどうかわからないという問題があります。
そのため、一時的に終了した後に子を削除するのが最善です。
どういうわけか、これはすべて私にとってエレガントではないので、私は自分自身(そしてあなた)に尋ねています:
これを最もエレガントに解決するにはどうすればよいですか?
この状況では、スーパーバイザをまったく使用しない方がよいでしょうか?
erlang - Erlang: タスク スケジューラを書くことで、どのスーパーバイザー ツリーを終了する必要がありますか?
主に教育目的で、タスクを作成しようとしています (タスクは open_port({spawn_executable, Command})) スケジューラです。
私は次のような木になってしまいます
言い換えると:
- トップスーパーバイザーはスケジューラーとレシーバーを開始し、それらが有効であることを確認します
- レシーバーは中間スーパーバイザーを開始します
- 中間スーパーバイザーがディスパッチャーを開始し、それが有効であることを確認します
- ディスパッチャが下部スーパーバイザを開始
最下層のスーパーバイザーは、要求に応じてタスクを開始し、エラーが発生した場合にタスクが再開されるようにします
スケジューラーはいつでも、実行されるべきタイムスタンプを持つタスクを受け入れる準備ができています
- タイムスタンプが満たされると、いくつかの event_manager に通知します
- レシーバーは同じイベント マネージャーから通知を受け、中間スーパーバイザーを介してメッセージをディスパッチャーに渡します。
- ディスパッチャーには、ステートレスではないビジネス ロジックがあります。たとえば、ある種のタスクを同時に実行することはできません。
- すべての条件が満たされると、ディスパッチャーはタスクを下部のスーパーバイザーに渡します。これにより、通常の終了が得られるか、いくつかのしきい値がバイパスされるまで、タスクが確実に実行されます
- 一番下のスーパーバイザーがメッセージを返し、それがイベント マネージャーに上から下に渡されます
- スケジューラは最終的にこのメッセージを受け取り、タスクをキューから削除するか、キューに再登録します。
質問は次のとおりです。
- ビヘイビアーを正しく使用していますか?
- 構造が複雑すぎませんか?(ただし、将来的にはシステムは分散化される予定です。)
- 同時に4つの動作を実装する4つの代わりに、レシーバー+ミドルスーパーバイザーとディスパッチャー+ボトムスーパーバイザーを2つのモジュールに組み合わせる方法はありますか?
- または、レシーバー + ディスパッチャー + ボトム スーパーバイザーを 1 つのモジュールに組み合わせて、中間スーパーバイザーの必要性をなくし、gen_event + gen_server + スーパーバイザーの動作を同時に実装する方法はありますか?
- OO 言語のインターフェイスまたは多重継承としての振る舞いを間違って考えているのでしょうか? (それで私は質問 3 と 4 を尋ねます。)
前もって感謝します。
PS IMO、一方で、構造が複雑すぎます。一方、このような構造では、そのブロックを分散させることができます (たとえば、多くのスケジューラーを 1 つのレシーバーに、1 つのスケジューラーを多くのレシーバーに、多くのスケジューラーを多くのレシーバーに、多くのディスパッチャーを各レシーバーに、さらに多くのボトム スーパーバイザーを各ディスパッチャーに)。 - 独自の監督ポリシーを持つすべてのレイヤー)。複雑さと拡張性のバランス ポイントはどこにありますか?
erlang - 子を再起動している間、スーパーバイザーは通話をブロックしますか?
ここで何が起こっているのかを理解しようとしています:
MaxR, MaxT
メカニズムをトリガーせずに 1 つのクライアントを周期的に再起動しているスーパーバイザがいます。クライアントは、レート制限をトリガーしないほどゆっくりとクラッシュします。
supervisor:which_children/1
子のセットを使用して実際に適応させる別のメカニズムがあったはずdelete_child/2, start_child/2
です (USB デバイスをスキャンして、見つかったデバイスごとに 1 つのスーパーバイザーの子を持たせようとします)。
これは通常、レート制限に対するセーフティ ネットのように動作しますが、奇妙なことに、子を削除して開始するメカニズムがまったく呼び出されないように見えます。
何が起こっているのかを知るためにsupervisor:which_children/1
、シェルから呼び出しましたが、呼び出しがブロックされ、返されないように見えます。
スーパーバイザが子を再起動しようとしている間、スーパーバイザへの呼び出しがブロックされる可能性はありますか?
補遺:
子の開始中にクラッシュが発生したようです:
erlang - 到達したスーパーバイザーが、問題のある子のみを削除するにはどうすればよいですか?
私には、one_for_one
似たような完全に独立した子供を扱う監督者がいます。
1人の子供に問題がある場合、クラッシュとトリガーを繰り返します。
自分自身をシャットダウンし、それ以外の場合は正常に実行し続けるすべての無実の子供たちを終了させます。
標準のErlangスーパーバイザーから監視ツリーを構築するにはどうすればよいですか?これは、問題のある1人の子の再起動を停止し、他の子をそのままにします。
一人っ子で上司を増員することを考えていましたが、これは私には重いようです。
これを処理する他の方法はありますか?
erlang - Erlang クラスター内のすべてのノードで gen_server を実行する最良の方法は何ですか?
Erlang で監視ツールを構築しています。クラスターで実行する場合、すべてのノードで一連のデータ収集機能を実行し、単一の「レコーダー」ノードで RRD を使用してそのデータを記録する必要があります。
現在のバージョンには、マスター ノード ( rolf_node_sup
) で実行されているスーパーバイザがあり、クラスタ内の各ノードで 2 番目のスーパーバイザを実行しようとします ( rolf_service_sup
)。次に、ノード上の各スーパーバイザは、マスター ノードの gen_server にメッセージを送信する一連のプロセスを開始および監視する必要があります ( rolf_recorder
)。
これはローカルでのみ機能します。どのリモート・ノードでもスーパーバイザーは開始されません。次のコードを使用して、レコーダー ノードからノード上のスーパーバイザーをロードしようとします。
スーパーバイザーは実際にはローカル プロセス専用に設計されていると示唆する人を何人か見つけました。例えば
クラスター内のすべてのノードで監視されたコードを実行するという私の要件を実装するための最も OTP の方法は何ですか?
- 分散アプリケーションは、分散スーパーバイザ ツリーの代替案の 1 つとして提案されています。これらは私のユースケースには合いません。ノード間のフェールオーバーを提供しますが、一連のノードでコードを実行したままにします。
- プールモジュールは興味深いものです。ただし、すべてのノードではなく、現在最も負荷の低いノードでジョブを実行できます。
proc_lib:spawn_link
別の方法として、各ノードでスーパーバイザを起動するために使用する、監視対象の「プロキシ」プロセスのセット (ノードごとに 1 つ) をマスター上に作成することもできます。ノードで何か問題が発生した場合、プロキシ プロセスは終了し、そのスーパーバイザによって再起動され、リモート プロセスが再起動されます。ここでは、 slaveモジュールが非常に役立ちます。- または多分私は過度に複雑です。ノードを直接監視するのは悪い考えです。代わりに、より疎結合の方法でデータを収集するようにアプリケーションを設計する必要があります。複数のノードでアプリを実行してクラスターを構築し、1 つをマスターに指定して、そのままにしておきます。
いくつかの要件:
- アーキテクチャは、手動で介入することなく、プールに参加したりプールから離れたりするノードに対処できる必要があります。
- 簡単にするために、少なくとも最初はシングルマスターソリューションを構築したいと思います。
- 私の実装では、手巻きのコードよりも既存の OTP 機能を使用したいと考えています。
erlang - Erlang:監督者を監督するのは誰ですか?
私がこれまでに見たすべてのErlangスーパーバイザーの例では、通常、ツリー全体を監視する「マスター」スーパーバイザーがいます(または少なくともスーパーバイザーツリーのルートノードです)。「マスター」スーパーバイザーが壊れた場合はどうなりますか?「マスター」-スーパーバイザーはどのように監視されるべきですか?典型的なパターンはありますか?