我正在编写一个ejabberd模块,需要在以下两种情况下执行不同的清理操作:
我考虑以下解决方案:
is_there_running_instances() ->
{Results, _} = rpc:multicall(nodes(), ?MODULE, ejabberd_loaded_modules, []),
lists:member(?MODULE, lists:append(Results)).
ejabberd_loaded_modules() -> ???.
但不知道如何获取已加载模块的列表。我该怎么做?或者我的问题有更好的解决方案吗?
答案 0 :(得分: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]
答案 1 :(得分:1)
试试
gen_mod:loaded_modules(Host)
是你需要的
答案 2 :(得分:0)
首先获取所有已加载的模块列表,其中包含代码: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).