2017-01-23 2 views
2

私は独自のErlangノードで動作するイベントマネージャを持っています。単純なイベントブローカーとして使用し、他のノード上の他のアプリケーションが独自のイベントハンドラーを追加してそれを購読できるようにしたいと思います。私が何か間違ったことをやっている場合、私は疑問に思って、だから今ローカルのイベントハンドラをリモートイベントマネージャに追加することは可能ですか

{'EXIT',{undef,[{event_handler_a,init,[[]],[]}, 
       {gen_event,server_add_handler,4, 
          [{file,"gen_event.erl"},{line,429}]}, 
       {gen_event,handle_msg,5,[{file,"gen_event.erl"},{line,270}]}, 
       {proc_lib,init_p_do_apply,3, 
          [{file,"proc_lib.erl"},{line,247}]}]}} 

は私のテストのセットアップはこれを実行している場合は、私のようなエラーが出ます(ごめんひどい字下げ) enter image description here

次のようになりますまたはこのアーキテクチャが単に可能でない場合。私のイベントハンドラのロジックはアプリケーションと完全に関連しているので、私はアプリケーションリリース内に置いておきたいと思っています。私のイベントマネージャーリリース内の各アプリケーション用のイベントハンドラーを持つことは、恐らく本当に面倒なことになるだろう。

+1

私はgen_event' 'について多くを知らないが、しかし、そのエラーはgen_event'がevent_handler_a'呼び出そうと 'のように見えます。init([])'と、そのモジュールのいずれかまたはその関数はそのErlangノードに定義/ロードされていませんでした。 – Dogbert

+0

@Dogbert私はこれについて忘れました。イベントマネージャがイベントハンドラからinit/1コールバックを呼び出す場合は、ノード名を指定する必要があります。残念なことに、このドキュメントでは、 'Handler = Module |を使用して ' add_handler(EventMgrRef、Handler、Args) - > Result'を示しています。 {Module、Id} ' – ITChap

+0

あなたは' Args'としてそれを渡すことができると思いますので、 'gen_event:add_handler(_、_、node1 @ host1)'です。 – Dogbert

答えて

5

いいえ、これはできません。 gen_eventは、コールバックモジュールのコード(gen_event:add_handler/3の引数として渡すコード)が、のイベントマネージャと同じプロセスで実行されるという点で、他の動作とは少し異なります。したがって、イベントマネージャがリモートノード上で実行されている場合、イベントハンドラは同じノード上で実行されます。

これを実現する1つの方法は、イベントを目的のノード上のプロセスに転送するイベントハンドラコールバックモジュールを作成することです。次に、このような何か行うことができます:

gen_event:add_handler({event_manager, [email protected]}, my_event_forwarder, [self()]). 
+0

それは私が思ったものです。私は、init引数として 'fun()'をとり、すべてのイベントを 'fun()'に渡す非常に汎用的なハンドラを作成することもできます。サブスクリプションは、いつも異なる 'fun()'を持つ同じハンドラモジュールを追加して別のことをすることになります。 – ITChap

+1

funが定義されているモジュールは、呼び出されたノードにロードする必要があります。 – legoscia

関連する問題