From 9679c46e157b7c2c4e2178676f1d1e183126dcb8 Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Sun, 12 Jul 2020 12:19:14 -0700 Subject: [PATCH] WIP: Supervisor-based plugin base Signed-off-by: Alek Ratzloff --- lib/contrib/fortune.ex | 2 +- lib/contrib/linkbot.ex | 2 +- lib/contrib/markov/markov.ex | 2 +- lib/contrib/on_connect.ex | 12 +++--- lib/contrib/wordbot/wordbot.ex | 2 +- lib/{ => core}/core.ex | 2 +- lib/irc/irc.ex | 3 +- lib/plugin/base.ex | 2 +- lib/plugin/gen_server.ex | 50 ------------------------- lib/plugin/{supervisor.ex => plugin.ex} | 27 +++++++++---- 10 files changed, 33 insertions(+), 71 deletions(-) rename lib/{ => core}/core.ex (98%) delete mode 100644 lib/plugin/gen_server.ex rename lib/plugin/{supervisor.ex => plugin.ex} (66%) diff --git a/lib/contrib/fortune.ex b/lib/contrib/fortune.ex index 773deb3..bc17c70 100644 --- a/lib/contrib/fortune.ex +++ b/lib/contrib/fortune.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Fortune do - use Omnibot.Plugin.GenServer + use Omnibot.Plugin @fortunes [ "Reply hazy, try again", diff --git a/lib/contrib/linkbot.ex b/lib/contrib/linkbot.ex index 1c51045..de6af26 100644 --- a/lib/contrib/linkbot.ex +++ b/lib/contrib/linkbot.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Linkbot do - use Omnibot.Plugin.GenServer + use Omnibot.Plugin require Logger @default_config timeout: 30_000 diff --git a/lib/contrib/markov/markov.ex b/lib/contrib/markov/markov.ex index b19305e..d18415f 100644 --- a/lib/contrib/markov/markov.ex +++ b/lib/contrib/markov/markov.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Markov do - use Omnibot.Plugin.Supervisor + use Omnibot.Plugin alias Omnibot.Contrib.Markov.Chain require Logger diff --git a/lib/contrib/on_connect.ex b/lib/contrib/on_connect.ex index a732a06..5fc2a16 100644 --- a/lib/contrib/on_connect.ex +++ b/lib/contrib/on_connect.ex @@ -1,15 +1,13 @@ defmodule Omnibot.Contrib.OnConnect do - use Omnibot.Plugin.GenServer + use Omnibot.Plugin require Logger @default_config [channels: :all, commands: []] @impl true - def on_msg(irc, msg) do - if msg.command == "001" do - Logger.debug("Got welcome message") - cfg()[:commands] - |> Enum.each(fn [cmd | params] -> Irc.send_msg(irc, cmd, params) end) - end + def on_msg(irc, %Irc.Msg {command: "001"}) do + Logger.info("Running OnConnect commands") + cfg()[:commands] + |> Enum.each(fn [cmd | params] -> Irc.send_msg(irc, cmd, params) end) end end diff --git a/lib/contrib/wordbot/wordbot.ex b/lib/contrib/wordbot/wordbot.ex index aa79c44..0971ec6 100644 --- a/lib/contrib/wordbot/wordbot.ex +++ b/lib/contrib/wordbot/wordbot.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Contrib.Wordbot do - use Omnibot.Plugin.Supervisor + use Omnibot.Plugin alias Omnibot.{Contrib.Wordbot, State, Util} require Logger diff --git a/lib/core.ex b/lib/core/core.ex similarity index 98% rename from lib/core.ex rename to lib/core/core.ex index 257e9b0..db05f60 100644 --- a/lib/core.ex +++ b/lib/core/core.ex @@ -1,5 +1,5 @@ defmodule Omnibot.Core do - use Omnibot.Plugin.GenServer + use Omnibot.Plugin alias Omnibot.State @default_config [channels: :all] diff --git a/lib/irc/irc.ex b/lib/irc/irc.ex index a027006..f419adb 100644 --- a/lib/irc/irc.ex +++ b/lib/irc/irc.ex @@ -33,7 +33,8 @@ defmodule Omnibot.Irc do Task.Supervisor.async_stream_nolink( Omnibot.RouterSupervisor, plugins, - fn {plugin, _plug_cfg} -> plugin.on_msg(irc, msg) end, + # Spin up tasks to handle messages in case handle_msg() hangs + fn {plugin, _plug_cfg} -> plugin.handle_msg(irc, msg) end, timeout: 30_000, on_timeout: :kill_task ) |> Stream.run() diff --git a/lib/plugin/base.ex b/lib/plugin/base.ex index edaf3f4..cbfcc6d 100644 --- a/lib/plugin/base.ex +++ b/lib/plugin/base.ex @@ -79,7 +79,7 @@ defmodule Omnibot.Plugin.Base do end end - #@callback handle_msg(irc :: pid(), msg :: %Omnibot.Irc.Msg{}) :: any + @callback handle_msg(irc :: pid(), msg :: %Omnibot.Irc.Msg{}) :: any @callback on_msg(irc :: pid(), msg :: %Omnibot.Irc.Msg{}) :: any @callback on_channel_msg(irc :: pid(), channel :: String.t(), nick :: String.t(), line :: String.t()) :: any @callback on_channel_msg( diff --git a/lib/plugin/gen_server.ex b/lib/plugin/gen_server.ex deleted file mode 100644 index 5842e7f..0000000 --- a/lib/plugin/gen_server.ex +++ /dev/null @@ -1,50 +0,0 @@ -defmodule Omnibot.Plugin.GenServer do - defmacro __using__([]) do - quote do - use Omnibot.Plugin.Base - use GenServer - - def start_link(opts) do - cfg = opts[:cfg] - state = opts[:state] - GenServer.start_link(__MODULE__, {cfg, state}, opts) - end - - def cfg() do - GenServer.call(__MODULE__, :cfg) - end - - def state() do - GenServer.call(__MODULE__, :state) - end - - def update_state(update) do - GenServer.cast(__MODULE__, {:state, update}) - end - - ## Server callbacks - - @impl GenServer - def init({cfg, state}) do - state = state || on_init(cfg) - {:ok, {cfg, state}} - end - - @impl GenServer - def handle_call(:cfg, _from, {cfg, state}) do - {:reply, cfg, {cfg, state}} - end - - @impl GenServer - def handle_call(:state, _from, {cfg, state}) do - {:reply, state, {cfg, state}} - end - - @impl GenServer - def handle_cast({:state, update}, {cfg, state}) do - {:noreply, {cfg, apply(update, [state])}} - end - end - end -end - diff --git a/lib/plugin/supervisor.ex b/lib/plugin/plugin.ex similarity index 66% rename from lib/plugin/supervisor.ex rename to lib/plugin/plugin.ex index 701582b..ae1abc5 100644 --- a/lib/plugin/supervisor.ex +++ b/lib/plugin/plugin.ex @@ -1,4 +1,4 @@ -defmodule Omnibot.Plugin.Supervisor do +defmodule Omnibot.Plugin do @default_opts [include_base: true, opts: [strategy: :one_for_one]] defmodule CfgState do @@ -32,31 +32,44 @@ defmodule Omnibot.Plugin.Supervisor do end def cfg() do - Omnibot.Plugin.Supervisor.CfgState.cfg(__MODULE__.CfgState) + Omnibot.Plugin.CfgState.cfg(__MODULE__.CfgState) end def state() do - Omnibot.Plugin.Supervisor.CfgState.state(__MODULE__.CfgState) + Omnibot.Plugin.CfgState.state(__MODULE__.CfgState) end def update_state(fun) do - Omnibot.Plugin.Supervisor.CfgState.update_state(__MODULE__.CfgState, fun) + Omnibot.Plugin.CfgState.update_state(__MODULE__.CfgState, fun) end + @impl Omnibot.Plugin.Base + def handle_msg(irc, msg) do + GenServer.cast(__MODULE__, {:handle_msg, irc, msg}) + end + + @impl Omnibot.Plugin + def children(_cfg, _state), do: [] + ## Server callbacks @impl Supervisor def init({cfg, state}) do - base_children = [ - {Omnibot.Plugin.Supervisor.CfgState, cfg: cfg, state: state, name: __MODULE__.CfgState}, + {Omnibot.Plugin.CfgState, cfg: cfg, state: state, name: __MODULE__.CfgState}, ] children = (if unquote(opts[:include_base]), do: base_children, else: []) ++ children(cfg, state) Supervisor.init(children, unquote(opts[:opts])) end - @behaviour Omnibot.Plugin.Supervisor + def handle_cast({:handle_msg, irc, msg}, state) do + on_msg(irc, msg) + {:noreply, state} + end + + @behaviour Omnibot.Plugin + defoverridable Omnibot.Plugin end end