2

ローカルに登録すると、イベント フレームワークを問題なく開始できます。

gen_event:start_link({local, foo_event_container}).
gen_event:add_handler(foo_event_container, foo_event_handler, []).

registered() を呼び出すと foo_event_container が表示され、それにメッセージを送信すると、ハンドラーに表示されます。

ただし、ノードを再起動して試してみると

gen_event:start_link({global, foo_event_container}).

registered() はコンテナーを表示しません。コンテナーにハンドラーを追加しようとすると、

** exception exit: noproc
     in function  gen:call/4
     in call from gen_event:rpc/2

Sasl は追加情報を提供しません。この問題をグーグル検索すると、コンテナーを実行しているシェルが強制終了されたことが推測されますが、同じノードからアクセスしようとしているため、ここでは当てはまりません!

1) ここで何が起こっているのか、何か考えはありますか?
2) リモート コンテナーを使用するのが最適な設計ですか?それとも、すべてのサーバーがリモート プロセスにメッセージを送信するローカル コンテナーを使用する方がよいでしょうか?

ありがとう!

4

1 に答える 1

2

ローカル登録とグローバル登録は別個の名前空間です。ローカルに登録されたアイテムはグローバル登録として表示されず、その逆も同様です。(また、ローカル登録名はアトムでなければなりませんが、グローバル名は用語にすることができます)

グローバル登録が表示され、通常どおり pid を検索してその pid にメッセージを送信することにより、global:registered_names/0グローバルに登録されたプロセスに送信できます。global:send/2global:whereis_name/1

のような方法でハンドラを追加できるはずですgen_event:add_handler({global, Name}, Handler, Args)。ほとんどのモジュールには、ルックアップを行うgen_*など、プロセス名に対処するためのコードが含まれています。{global, Name}global

最後に、start_linkシェルからプロセスを実行し、シェルをクラッシュさせる式を評価すると、そのプロセスは終了します。リンク経由でシェル エラーによって強制終了されました。リンクなしで開始するか、これを避けたい場合はスーパーバイザーの下で start_link してください。通常、何かをシェル プロセスにリンクするのは悪い考えです。タイプミスがあると、作業中のプロセスがシャットダウンしてしまうからです。

于 2011-02-18T21:40:51.517 に答える