Files
omnibot/lib/module_supervisor.ex
Alek Ratzloff 4083b5b858 Add default_config, and cfg[:timeout] for tasks
- Using the @default_config attribute in a module will fill out a default
value.
- cfg[:timeout] sets the timeout for the task for this module to finish.
- Update Omnibot.Irc.route_msg/2 to have each task spawn a second task,
  while the first task waits for its child to finish, otherwise killing
  it.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
2020-06-13 21:47:46 -04:00

62 lines
1.7 KiB
Elixir

defmodule Omnibot.ModuleSupervisor do
@moduledoc false
use Supervisor
require Logger
alias Omnibot.State
def start_link(opts \\ []) do
Supervisor.start_link(__MODULE__, opts[:cfg], opts)
end
@impl true
def init(cfg) do
compile_files(cfg.module_paths || [])
# These are modules that need to be loaded for core functionality of the bot
core = [
Omnibot.Core
]
# Map the modules in the configuration to the children
children =
for mod <- (core ++ cfg.modules) do
case mod do
{name, cfg} -> {name, cfg: cfg ++ name.default_config(), name: name}
name -> {name, cfg: name.default_config(), name: name}
end
end
# Add each child to the "loaded modules" list in the State
Enum.each(children, fn {module, opts} -> State.add_loaded_module({module, opts[:cfg]}) end)
Supervisor.init(children, strategy: :one_for_one)
end
defp compile_files([]), do: nil
defp compile_files([{path, opts} | module_paths]) do
case {File.exists?(path), File.dir?(path)} do
{_, true} -> compile_dir(path, opts[:recurse] || false)
{true, false} -> Code.require_file(path)
{_, _} -> Logger.error("module path '#{path}' does not exist, it will not be loaded")
end
compile_files(module_paths)
end
defp compile_files([path | module_paths]) do
compile_files([{path, []} | module_paths])
end
defp compile_dir(path, recurse) do
files =
File.ls!(path)
|> Enum.map(fn file -> {Path.join(path, file), [recurse: recurse]} end)
|> Enum.filter(fn {file, [recurse: recurse]} ->
(!File.dir?(file) || recurse) && File.exists?(file)
end)
compile_files(files)
end
end