Add a buffer for slowing message output to avoid flooding out the bot
This commit is contained in:
parent
38d3ae44b4
commit
6e8e3172c9
1 changed files with 79 additions and 0 deletions
79
lib/nulform/buffer.ex
Normal file
79
lib/nulform/buffer.ex
Normal file
|
@ -0,0 +1,79 @@
|
|||
defmodule Nulform.Buffer do
|
||||
use GenServer.Behaviour
|
||||
@moduledoc """
|
||||
A buffer takes outgoing messages from the bot and sends them to the
|
||||
given connection process with a delay to prevent the bot from flooding
|
||||
itself out of the network.
|
||||
|
||||
The algorithm is as follows (reasonable values are t = 2, m = 10):
|
||||
1. Read messages from input
|
||||
2. Insert messages into queue
|
||||
3. Set timer to be current time, if lower
|
||||
4. For each message
|
||||
4.1. Raise timer value by t
|
||||
4.2. If timer value is higher than current time + m, next send is
|
||||
at current time + t, otherwise send message immediately
|
||||
"""
|
||||
|
||||
defrecord Data,
|
||||
connection: nil,
|
||||
buffer: [] :: list,
|
||||
waiting: :false,
|
||||
timer: 0 :: integer
|
||||
|
||||
def init(pid) do
|
||||
data = Data.new(connection: pid)
|
||||
{:ok, data}
|
||||
end
|
||||
|
||||
def handle_cast(msg, data) do
|
||||
data = data.buffer data.buffer ++ [msg]
|
||||
|
||||
data = handle_buffer data
|
||||
{:noreply, data}
|
||||
end
|
||||
|
||||
def handle_info(msg, data) do
|
||||
case msg do
|
||||
{:send_message} ->
|
||||
data = send_message data
|
||||
data = handle_buffer data
|
||||
end
|
||||
{:noreply, data}
|
||||
end
|
||||
|
||||
|
||||
defp handle_buffer(data) do
|
||||
{_, time, _} = :erlang.now()
|
||||
if data.timer < time do
|
||||
data = data.timer time
|
||||
end
|
||||
|
||||
if (data.timer - time) <= 10 do
|
||||
if not Enum.empty? data.buffer do
|
||||
data = send_message data
|
||||
data = data.waiting :false
|
||||
end
|
||||
else
|
||||
if (not Enum.empty? data.buffer) and not data.waiting do
|
||||
{:ok, timer} = :timer.send_after 2000, {:send_message}
|
||||
data = data.waiting :true
|
||||
end
|
||||
end
|
||||
|
||||
data
|
||||
end
|
||||
|
||||
defp send_message(data) do
|
||||
data = data.waiting :false
|
||||
|
||||
if not Enum.empty? data.buffer do
|
||||
[msg | tail] = data.buffer
|
||||
data = data.buffer tail
|
||||
data.connection <- {:nulform, :msg_out, msg}
|
||||
data = data.timer data.timer + 2
|
||||
else
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue