2013-11-01 59 views
0

我正在寫一個ejabberd模塊,需要在以下兩種情況下,在停止執行不同的清理操作:如何獲取加載的ejabberd模塊列表?

  • 同樣的模塊,在當前時刻其他羣集節點上運行。
  • 這是我模塊的最後一個仍在運行的實例。

我考慮了以下解決方案:

is_there_running_instances() -> 
    {Results, _} = rpc:multicall(nodes(), ?MODULE, ejabberd_loaded_modules, []), 
    lists:member(?MODULE, lists:append(Results)). 

ejabberd_loaded_modules() -> ???. 

但是不知道怎麼去加載的模塊列表。我該怎麼做?或者是我的問題有更好的解決方案?

回答

1

嘗試,如果

gen_mod:loaded_modules(Host) 

是你所需要的

1

code:all_loaded/0返回類型爲{ModuleName,ModuleAbsolutePath}的元組列表,其中ModuleName是原子,ModuleAbsolutePath是字符串。 您可以使用路徑信息過濾此列表,並將其解壓縮以僅獲取其包含的模塊。我與eunit庫測試它加載所有模塊後:

26> Filter = fun(Path,Lib) -> string:str(Path,Lib) > 0 end.       
#Fun<erl_eval.12.80484245> 
27> [Mod || {Mod,Path} <- code:all_loaded() , is_list(Path), Filter(Path,"eunit")]. 
[eunit,eunit_proc,eunit_test,eunit_data,eunit_surefire, 
eunit_serial,eunit_tests,eunit_autoexport,eunit_tty, 
eunit_server,eunit_striptests,eunit_lib,eunit_listener] 
0

首先獲取與代碼的所有加載的模塊列表:all_loaded/0而不是使用「mod_」preffix過濾結果。

ejabberd_loaded_modules() -> 
    AllLoaded = code:all_loaded(), 
    Filter = fun({Module, _}) -> 
     case re:run(atom_to_list(Module), "mod_") of 
      {match,[{0,4}]} -> true; 
      _ -> false 
     end 
    end, 
    lists:filter(Filter, AllLoaded). 

此外,您可以執行行爲檢查。它應該是gen_mod。

is_gen_mod(Module) -> 
    BehavioursList = 
    case lists:getkey(1, behaviour, Module:module_info(attributes)) of 
     {behaviour, L} -> L; 
     false -> [] 
    end, 
    lists:member(gen_mod, BehavioursList). 

在這種情況下ejabberd_loaded_modules/0函數將是:

ejabberd_loaded_modules() -> 
    ... 
    ModPreffixed = lists:filter(Filter, AllLoaded), 
    lists:filter(fun is_gen_mod/1, ModPreffixed).