これは基本的に正確に行い、私のexrmプロジェクト、からの抜粋です:それは、プラグインの動作を実装する任意のモジュールを見つける:行動に類似している検討する
@doc """
Loads all plugins in all code paths.
"""
@spec load_all() :: [] | [atom]
def load_all, do: get_plugins(ReleaseManager.Plugin)
# Loads all modules that extend a given module in the current code path.
@spec get_plugins(atom) :: [] | [atom]
defp get_plugins(plugin_type) when is_atom(plugin_type) do
available_modules(plugin_type) |> Enum.reduce([], &load_plugin/2)
end
defp load_plugin(module, modules) do
if Code.ensure_loaded?(module), do: [module | modules], else: modules
end
defp available_modules(plugin_type) do
# Ensure the current projects code path is loaded
Mix.Task.run("loadpaths", [])
# Fetch all .beam files
Path.wildcard(Path.join([Mix.Project.build_path, "**/ebin/**/*.beam"]))
# Parse the BEAM for behaviour implementations
|> Stream.map(fn path ->
{:ok, {mod, chunks}} = :beam_lib.chunks('#{path}', [:attributes])
{mod, get_in(chunks, [:attributes, :behaviour])}
end)
# Filter out behaviours we don't care about and duplicates
|> Stream.filter(fn {_mod, behaviours} -> is_list(behaviours) && plugin_type in behaviours end)
|> Enum.uniq
|> Enum.map(fn {module, _} -> module end)
end
これらのうちどれくらいをお持ちになりますか?たぶんソースコードのどこかに、おそらくスーパーバイザー仕様の中にそれらのリストを保持して、それぞれが別のプロセスで実行する方が簡単かもしれません。 –