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>
This commit is contained in:
2020-06-13 21:47:46 -04:00
parent a6a07adf7a
commit 4083b5b858
5 changed files with 30 additions and 11 deletions

View File

@@ -2,6 +2,8 @@ defmodule Omnibot.Contrib.Linkbot do
use Omnibot.Module use Omnibot.Module
require Logger require Logger
@default_config timeout: 30_000
defmodule Client do defmodule Client do
use Tesla use Tesla
@@ -13,6 +15,7 @@ defmodule Omnibot.Contrib.Linkbot do
def get_title(url) do def get_title(url) do
if should_get?(url) do if should_get?(url) do
Process.sleep(11_000)
resp = get!(url) resp = get!(url)
%{"title" => title} = Regex.named_captures(@title_regex, resp.body) %{"title" => title} = Regex.named_captures(@title_regex, resp.body)
title title

View File

@@ -2,6 +2,8 @@ defmodule Omnibot.Core do
use Omnibot.Module use Omnibot.Module
alias Omnibot.State alias Omnibot.State
@default_config [channels: :all]
@impl true @impl true
def on_join(irc, channel, nick) do def on_join(irc, channel, nick) do
cfg = State.cfg() cfg = State.cfg()

View File

@@ -32,12 +32,22 @@ defmodule Omnibot.Irc do
channel = Msg.channel(msg) channel = Msg.channel(msg)
State.channel_modules(channel) State.channel_modules(channel)
|> Enum.each(fn {module, _} -> |> Enum.each(fn {module, mod_cfg} ->
# Create a new task for each module # Create a new task for each module
{:ok, _task} = Task.Supervisor.start_child( {:ok, _task} =
Task.Supervisor.start_child(
Omnibot.RouterSupervisor,
fn ->
task = Task.Supervisor.async(
Omnibot.RouterSupervisor, Omnibot.RouterSupervisor,
fn -> module.on_msg(irc, msg) end 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)
end end
@@ -54,7 +64,7 @@ defmodule Omnibot.Irc do
# Wait for first message # Wait for first message
send_msg(self(), "NICK", cfg.nick) send_msg(self(), "NICK", cfg.nick)
send_msg(self(), "USER", [cfg.user, "0", "*", cfg.real]) send_msg(self(), "USER", [cfg.user, "0", "*", cfg.real])
:inet.setopts(socket, [active: true]) :inet.setopts(socket, active: true)
{:ok, socket} {:ok, socket}
end end

View File

@@ -20,6 +20,9 @@ defmodule Omnibot.Module do
@impl true @impl true
def on_init(_cfg), do: nil def on_init(_cfg), do: nil
@impl true
def default_config(), do: @default_config
def commands(), do: MapSet.to_list(@commands) def commands(), do: MapSet.to_list(@commands)
end end
end end
@@ -97,6 +100,7 @@ defmodule Omnibot.Module do
defoverridable Module defoverridable Module
@commands MapSet.new() @commands MapSet.new()
@default_config []
@before_compile Omnibot.Module.Hooks @before_compile Omnibot.Module.Hooks
end end
end end
@@ -114,6 +118,7 @@ defmodule Omnibot.Module do
@callback on_part(irc :: pid(), channel :: String.t(), nick :: String.t()) :: any @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_kick(irc :: pid(), channel :: String.t(), nick :: String.t(), target :: String.t()) :: any
@callback on_init(cfg :: any) :: any @callback on_init(cfg :: any) :: any
@callback default_config() :: any
defmacro command(cmd, opts) do defmacro command(cmd, opts) do
quote generated: true do quote generated: true do

View File

@@ -15,16 +15,15 @@ defmodule Omnibot.ModuleSupervisor do
# These are modules that need to be loaded for core functionality of the bot # These are modules that need to be loaded for core functionality of the bot
core = [ core = [
{Omnibot.Core, cfg: [channels: :all]}, Omnibot.Core
] ]
# Map the modules in the configuration to the children # Map the modules in the configuration to the children
children = children =
core ++ for mod <- (core ++ cfg.modules) do
for mod <- cfg.modules do
case mod do case mod do
{name, cfg} -> {name, cfg: cfg, name: name} {name, cfg} -> {name, cfg: cfg ++ name.default_config(), name: name}
name -> {name, cfg: [], name: name} name -> {name, cfg: name.default_config(), name: name}
end end
end end