2011-02-18 10 views
2

ためgen_eventグローバルを使用して:アーラン:私はそれをローカルに登録したときに、私はうまく私のイベントフレームワークを開始することができますリモートマネージャ

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

登録呼び出し()foo_event_containerを示しており、私はそれにメッセージを送信するとき、彼らは示してハンドラ内でしかし

、私は、ノードを再起動してみたときに

gen_event:start_link({global, foo_event_container}). 

コンテナは表示されません)(登録、そして私はそれが私が

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

は、Saslを取得 にハンドラを追加しようとすると、追加情報を提供していないので、この問題を尋ねると、コンテナを実行しているシェルが終了したと推測されます。これは、同じノードからアクセスしようとしているためです。

1)ここで何が起こっているのですか?
2)リモートコンテナを設計するのが最適か、または各サーバーがリモートコンテナにメッセージを送信するローカルコンテナを使用する方がよいでしょうか?

ありがとうございます!

答えて

2

ローカル登録とグローバル登録は別々の名前空間です。ローカルに登録されたアイテムはグローバル登録として表示されず、逆も同様です。 (グローバル名が条件になることができますがまた、ローカル登録名は、原子でなければならない)

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

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

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

+1

はい! gen_event:add_handler({global、foo_event_container}、foo_event_handler、[])でグローバルタプルを使用すると、完璧に動作します。 (それがどこかで文書化されていれば素晴らしかった...) – tkersh

+0

これも私を困惑させた。これについてのドキュメントがない理由が不思議です.... –

+0

マニュアルを参照する必要がある場合は、[link](http://erlang.org/doc/man/global.html) –

関連する問題