3

Manning の Erlang & OTP In Actionを読んでいます。とても良い本だと思います。素敵な TCP サーバーの例が含まれていますが、UDP サーバーを書きたいと思います。これが、これまでのアプリの構造です。

my_app                        % app behaviour
|-- my_sup                    % root supervisor 
    |-- my_server.erl         % gen_server to open UDP connection and dispatch
    |-- my_worker_sup         % simple_one_to_one supervisor to start workers
        |-- my_worker_server  % gen_server worker 

したがって、my_appが開始my_supし、 が開始され、 が開始されmy_worker_supますmy_server。UDP接続はmy_serverアクティブモードで開かれ、handle_info/2新しいUDPメッセージごとに呼び出され、それに応答してmy_worker_sup:start_child/2メッセージを処理のために新しいワーカープロセスに渡すように呼び出します。(実際には、最後の呼び出しstart_child/2は本の推奨に従って、詳細の一部を隠すために API 関数にラップされていますが、これは本質的に何が起こるかです。)

私は OTP 熱に苦しんでいますか? my_worker_server本当に gen_server の動作を実装する必要がありますか? 私my_worker_supはまったく必要ですか?

my_worker_sup呼び出しを介してファクトリとして使用できるように、このように設定しましたが、最初に状態を設定し、ワーカーをシャットダウンする前にメッセージを処理するためにワーカーの関数と関数start_child/2のみを使用します。init/1handle_info(timeout,State)

ワーカーを直接生成する必要がありますか? おそらく、別の行動がより適しているでしょうか?

ありがとう、HC

4

1 に答える 1

4

この質問に対する重要な答えは、「アプリケーションをどのようにクラッシュさせたいですか?」です。

労働者が死亡した場合、どうすればよいですか?これにより UDP 接続を含むすべてが停止する場合は、それらを my_server の下に直接 spawn_link するだけで、スーパバイザ ツリーは必要ありません。しかし、正常に再起動できるようにしたい場合や、他の何かをしたい場合は、通常、上の図の方が適しています。おそらく、my_server のワーカーにモニターを追加して、誰が生きているかを記録できるようにします。

私の utp erlang ライブラリでは、ほぼ同じ構成になっています。マスターは UDP ソケットを処理し、ETS に保持されているルーティング テーブルに基づいてワーカーに転送します。各ワーカーは接続状態を維持し、着信情報を処理できます。

状態を追跡しないため、最善の策はおそらく経由して実行しproc_lib:spawn_link、一時的なプロセスとして s_1_1 スーパーバイザーにフックすることです。そうすれば、あまりにも多くのクラッシュを強制的にスーパーバイザー ツリーに伝播させますが、それらを終了させることができますnormal。これにより、それらを 1 回だけ実行することができます。

my_server ですべてを直接処理することもできますが、データを同時に処理することはできません。これは、受け入れられる場合と受け入れられない場合があります。一般的なルールは、互いに隣り合って実行する必要がある、ブロックする、または何らかの方法で動作する必要がある同時作業がある場合に、新しいプロセスを生成することです。

于 2012-12-12T11:56:29.833 に答える