Как получить список загруженных модулей ejabberd?

Я пишу модуль ejabberd, и мне нужно выполнить различные действия по очистке при остановке в двух следующих случаях:

  • Этот же модуль в данный момент работает на других узлах кластера.
  • Это последний работающий экземпляр моего модуля.

Я рассматриваю следующее решение:

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

ejabberd_loaded_modules() -> ???.

Но не знаю, как получить список загруженных модулей. Как мне это сделать? Или моя проблема имеет лучшее решение?


person citxx    schedule 01.11.2013    source источник


Ответы (3)


попробуй, если

gen_mod:loaded_modules(Host)

это то, что вам нужно

person ppolv    schedule 05.11.2013

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]
person Pascal    schedule 05.11.2013

Прежде всего, получите список всех загруженных модулей с кодом: all_loaded/0, а затем отфильтруйте результат с префиксом «mod_».

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).
person sysoff    schedule 05.11.2013