2017-01-23 78 views
2

我有一個運行在其自己的Erlang節點中的事件管理器。我想將其用作簡單的事件代理,並讓其他應用程序在其他節點上通過添加自己的事件處理程序來訂閱它。是否可以將本地事件處理程序添加到遠程事件管理器

我的測試設置是這樣的(對不起可怕的壓痕) enter image description here

運行此我得到這樣一個錯誤:

{'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}]}]}} 

所以,現在,我想知道如果我做錯了什麼或者如果這種架構是不可能的。由於我的事件處理程序中的邏輯與我的應用程序完全相關,所以我寧願將其保留在我的應用程序發行版中。在我的事件管理器版本中爲每個應用程序設置一個事件處理程序可能會很快變得混亂。

+1

我不知道很多關於'gen_event',但這個錯誤看起來像'gen_event'試圖打電話'event_handler_a:初始化([])',要麼該模塊或該函數未在該Erlang節點上定義/加載。 – Dogbert

+0

@Dogbert我忘了這件事。如果事件管理器從事件處理程序調用init/1回調,則需要指定節點名稱。不幸的是,doc顯示 'add_handler(EventMgrRef,Handler,Args) - > Result' with'Handler = Module | {Module,Id}' – ITChap

+0

我想你可以通過'Args',所以'gen_event:add_handler(_,_,node1 @ host1)'。 – Dogbert

回答

5

不,這是不可能的。 gen_event與其他行爲有點不同,因爲回調模塊中的代碼(作爲參數傳遞給gen_event:add_handler/3的那個代碼)作爲事件管理器在相同的進程中運行。因此,如果事件管理器在遠程節點上運行,事件處理程序將在同一節點上運行。

實現此目的的一種方法是創建一個事件處理程序回調模塊,該模塊將事件轉發到所需節點上的進程。那麼你可以做這樣的事情:

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

這就是我的想法。我也可以創建一個非常通用的處理函數,它將init()作爲fun()的參數,並將所有事件傳遞給這個fun()。訂閱將總是添加具有不同'fun()'的相同處理程序模塊來完成不同的事情。 – ITChap

+1

請注意,fun中定義的模塊必須加載到調用它的節點上。 – legoscia

相關問題