Finish up Plugin.Supervisor, replace markov and wordbot implementations with it

Both markov and wordbot have some auxiliary processes that run to keep
track of things. Previously, they both had custom supervisors grafted on
to the Plugin.Base - now, this grafting is automated with
Plugin.Supervisor.

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-07-11 15:43:07 -07:00
parent 369c9824fb
commit 9a8c6f2472
7 changed files with 290 additions and 247 deletions

View File

@@ -1,32 +1,64 @@
defmodule Omnibot.Contrib.Markov do
use Omnibot.Plugin.Base
alias Omnibot.Contrib.Markov
use Supervisor
use Omnibot.Plugin.Supervisor
alias Omnibot.Contrib.Markov.Chain
require Logger
@default_config path: "markov", order: 2, save_every: 5 * 60
def start_link(opts) do
Supervisor.start_link(__MODULE__, opts[:cfg], opts)
@impl true
def children(_cfg, _state) do
[{Task, fn ->
Stream.timer(1000)
|> Stream.cycle()
|> Stream.each(fn _ -> save_chains() end)
|> Stream.run()
end}]
end
@impl true
def init(cfg) do
children = [
{Markov.Bot, cfg: cfg, name: Omnibot.Contrib.Markov.Bot},
{Task, fn -> save_loop(cfg) end}
]
Supervisor.init(children, strategy: :one_for_all)
end
defp save_loop(cfg) do
save_every = cfg[:save_every]
Process.sleep(save_every * 1000)
Markov.Bot.save_chains()
def on_init(_cfg) do
# Create the markov database
path = String.to_atom(cfg()[:path])
{:ok, db} = :dets.open_file(path, [:named_table])
chains = :ets.new(:markov_chains, [:public])
:dets.to_ets(db, chains)
:dets.close(db)
end
@impl true
def on_msg(irc, msg), do: Markov.Bot.on_msg(irc, msg)
def on_channel_msg(_irc, channel, nick, msg) do
train(channel, nick, msg)
end
@impl true
def on_channel_msg(irc, channel, nick, msg), do: Markov.Bot.on_channel_msg(irc, channel, nick, msg)
def train(channel, user, msg) do
chain = (user_chain(channel, user) || create_user_chain(channel, user))
|> Chain.train(msg)
true = update_user_chain(channel, user, chain)
end
def user_chain(channel, user) do
db = state()
case :ets.lookup(db, {channel, user}) do
[] -> nil
[{{^channel, ^user}, chains}] -> chains
end
end
def update_user_chain(channel, user, chain) do
db = state()
case user_chain(channel, user) do
nil -> :ets.insert_new(db, {{channel, user}, chain})
chain -> :ets.insert(db, {{channel, user}, chain})
end
end
defp create_user_chain(channel, user) do
true = update_user_chain(channel, user, %Chain{order: cfg()[:order]})
user_chain(channel, user)
end
def save_chains() do
# TODO
Logger.info("Saved markov chains")
end
end