diff --git a/lib/contrib/linkbot.ex b/lib/contrib/linkbot.ex index 22b2ba3..7bace2d 100644 --- a/lib/contrib/linkbot.ex +++ b/lib/contrib/linkbot.ex @@ -2,6 +2,8 @@ defmodule Omnibot.Contrib.Linkbot do use Omnibot.Module require Logger + @default_config timeout: 30_000 + defmodule Client do use Tesla @@ -13,6 +15,7 @@ defmodule Omnibot.Contrib.Linkbot do def get_title(url) do if should_get?(url) do + Process.sleep(11_000) resp = get!(url) %{"title" => title} = Regex.named_captures(@title_regex, resp.body) title diff --git a/lib/core.ex b/lib/core.ex index 891b65b..6fb2314 100644 --- a/lib/core.ex +++ b/lib/core.ex @@ -2,6 +2,8 @@ defmodule Omnibot.Core do use Omnibot.Module alias Omnibot.State + @default_config [channels: :all] + @impl true def on_join(irc, channel, nick) do cfg = State.cfg() diff --git a/lib/irc.ex b/lib/irc.ex index 876ed5c..6a450b2 100644 --- a/lib/irc.ex +++ b/lib/irc.ex @@ -32,12 +32,22 @@ defmodule Omnibot.Irc do channel = Msg.channel(msg) State.channel_modules(channel) - |> Enum.each(fn {module, _} -> + |> Enum.each(fn {module, mod_cfg} -> # Create a new task for each module - {:ok, _task} = Task.Supervisor.start_child( - Omnibot.RouterSupervisor, - fn -> module.on_msg(irc, msg) end - ) + {:ok, _task} = + Task.Supervisor.start_child( + Omnibot.RouterSupervisor, + fn -> + task = Task.Supervisor.async( + Omnibot.RouterSupervisor, + fn -> module.on_msg(irc, msg) end + ) + + # Time out after 10 seconds by default + timeout = mod_cfg[:timeout] || 10_000 + Task.await(task, timeout) + end + ) end) end @@ -54,7 +64,7 @@ defmodule Omnibot.Irc do # Wait for first message send_msg(self(), "NICK", cfg.nick) send_msg(self(), "USER", [cfg.user, "0", "*", cfg.real]) - :inet.setopts(socket, [active: true]) + :inet.setopts(socket, active: true) {:ok, socket} end diff --git a/lib/module.ex b/lib/module.ex index 9caf556..8772493 100644 --- a/lib/module.ex +++ b/lib/module.ex @@ -20,6 +20,9 @@ defmodule Omnibot.Module do @impl true def on_init(_cfg), do: nil + @impl true + def default_config(), do: @default_config + def commands(), do: MapSet.to_list(@commands) end end @@ -97,6 +100,7 @@ defmodule Omnibot.Module do defoverridable Module @commands MapSet.new() + @default_config [] @before_compile Omnibot.Module.Hooks end end @@ -114,6 +118,7 @@ defmodule Omnibot.Module do @callback on_part(irc :: pid(), channel :: String.t(), nick :: String.t()) :: any @callback on_kick(irc :: pid(), channel :: String.t(), nick :: String.t(), target :: String.t()) :: any @callback on_init(cfg :: any) :: any + @callback default_config() :: any defmacro command(cmd, opts) do quote generated: true do diff --git a/lib/module_supervisor.ex b/lib/module_supervisor.ex index 82575e4..2f8abb2 100644 --- a/lib/module_supervisor.ex +++ b/lib/module_supervisor.ex @@ -15,16 +15,15 @@ defmodule Omnibot.ModuleSupervisor do # These are modules that need to be loaded for core functionality of the bot core = [ - {Omnibot.Core, cfg: [channels: :all]}, + Omnibot.Core ] # Map the modules in the configuration to the children children = - core ++ - for mod <- cfg.modules do + for mod <- (core ++ cfg.modules) do case mod do - {name, cfg} -> {name, cfg: cfg, name: name} - name -> {name, cfg: [], name: name} + {name, cfg} -> {name, cfg: cfg ++ name.default_config(), name: name} + name -> {name, cfg: name.default_config(), name: name} end end