2011-02-18 49 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沒有提供任何額外的信息,並且使用googling這個問題產生一個猜測,即運行容器的shell已經被殺死了,這裏不是這種情況,因爲我試圖從同一個節點訪問它!

1)任何想法這裏發生了什麼?
2)有一個遠程容器是最好的設計,還是每個服務器都使用本地容器,它們都將消息發送到遠程進程會更好?

謝謝!

回答

2

本地註冊和全局註冊是獨立的命名空間。在本地註冊的項目不會顯示爲全球註冊,反之亦然。 (另外,本地註冊的名稱必須是原子,而全局名稱可以計算)

您的全球登記的,應當在global:registered_names/0出現了,你可以發送到全局註冊流程要麼global:send/2或通過查找PID與global:whereis_name/1和發送像往常一樣傳遞給該pid的消息。

您應該可以通過執行類似gen_event:add_handler({global, Name}, Handler, Args)的操作來添加處理程序。大多數gen_*模塊包含代碼來處理進程名稱,如{global, Name},以便爲您執行global查找。

最後,如果你從shell中獲取一個進程,然後評估一個導致shell崩潰的表達式,那麼這個進程將被終止 - 它只是通過鏈接被shell錯誤殺死。如果您想避免這種情況,請在沒有鏈接的情況下啓動它,或者在管理員下啓動它。將某些東西鏈接到shell進程通常是一個壞主意,因爲錯別字會關閉您正在使用的進程。

+1

是的!使用gen_event全局元組:add_handler({global,foo_event_container},foo_event_handler,[])完美地工作,謝謝。 (如果這是記錄在某處,那會很好......) – tkersh 2011-02-18 22:00:14