diff options
Diffstat (limited to 'lib/irc/plugin_supervisor.ex')
-rw-r--r-- | lib/irc/plugin_supervisor.ex | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/irc/plugin_supervisor.ex b/lib/irc/plugin_supervisor.ex new file mode 100644 index 0000000..ca092dc --- /dev/null +++ b/lib/irc/plugin_supervisor.ex @@ -0,0 +1,91 @@ +defmodule IRC.Plugin do + require Logger + + defmodule Supervisor do + use DynamicSupervisor + + def start_link() do + DynamicSupervisor.start_link(__MODULE__, [], name: __MODULE__) + end + + def start_child(module, opts \\ []) do + IO.inspect(module) + spec = %{id: {IRC.Plugin,module}, start: {IRC.Plugin, :start_link, [module, opts]}, name: module, restart: :transient} + DynamicSupervisor.start_child(__MODULE__, spec) + end + + @impl true + def init(_init_arg) do + DynamicSupervisor.init( + strategy: :one_for_one, + max_restarts: 10, + max_seconds: 1 + ) + end + end + + def dets(), do: to_charlist(LSG.data_path("/plugins.dets")) + + def setup() do + :dets.open_file(dets(), []) + end + + def enabled() do + :dets.foldl(fn + {name, true, _}, acc -> [name | acc] + _, acc -> acc + end, [], dets()) + end + + def start_all() do + for mod <- enabled(), do: {mod, IRC.Plugin.Supervisor.start_child(mod)} + end + + def declare(module) do + case get(module) do + :disabled -> :dets.insert(dets(), {module, true, nil}) + _ -> nil + end + end + + def start(module, opts \\ []) do + IRC.Plugin.Supervisor.start_child(module) + end + + @doc "Enables a plugin" + def enable(name), do: switch(name, true) + + @doc "Disables a plugin" + def disable(name), do: switch(name, false) + + @doc "Enables or disables a plugin" + def switch(name, value) when is_boolean(value) do + last = case get(name) do + {:ok, last} -> last + _ -> nil + end + :dets.insert(dets(), {name, value, last}) + end + + @spec get(module()) :: {:ok, last_start :: nil | non_neg_integer()} | :disabled + def get(name) do + case :dets.lookup(dets(), name) do + [{name, enabled, last_start}] -> {:ok, enabled, last_start} + _ -> :disabled + end + end + + def start_link(module, options \\ []) do + with {:disabled, {_, true, last}} <- {:disabled, get(module)}, + {:throttled, false} <- {:throttled, false} + do + module.start_link() + else + {error, _} -> + Logger.info("Plugin: #{to_string(module)} ignored start: #{to_string(error)}") + :ignore + end + end + +end + |