summaryrefslogtreecommitdiff
path: root/lib/irc/plugin_supervisor.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/irc/plugin_supervisor.ex')
-rw-r--r--lib/irc/plugin_supervisor.ex91
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
+