From 1eb18eb8ad114db86ae24b90e866888d57caf2d7 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Mon, 17 Sep 2018 19:33:11 +0200 Subject: implement a fifo and delay messages sent via unix socket prevent to gett banned for flood the irc channels by sending messages from via a queue. --- bot.lua | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/bot.lua b/bot.lua index 4bd71af..13c9f86 100644 --- a/bot.lua +++ b/bot.lua @@ -2,12 +2,53 @@ local cqueues = require("cqueues") local socket = require("cqueues.socket") local errno = require("cqueues.errno") +local condition = require("cqueues.condition") local loop = cqueues.new() local host, port, socketpath = ... +-------------------------------------------------------------------------------- +-- fifo queue + +local fifo = {} +function fifo.new() + local list = {} + list.next = list + list.prev = list + return setmetatable({list = list, condvar = condition.new()}, {__index = fifo}) +end + +function fifo:enqueue(data) + local node = { data = data} + node.next = self.list.next + node.prev = self.list + self.list.next.prev = node + self.list.next = node + self:signal() + return self +end + +function fifo:dequeue() + local node = self.list.prev + self.list.prev = node.prev + self.list.prev.next = node.next + return node.data +end + +function fifo:empty() + return self.list == self.list.next +end + +function fifo:signal() + self.condvar:signal() +end + +function fifo:getcv() + return self.condvar +end + -------------------------------------------------------------------------------- -- irc session local irc = { callbacks = {} } @@ -19,7 +60,8 @@ function irc.new(nick, username, password, realname) password = password, realname = realname or "albotty", hooks = {}, - channels = {} + channels = {}, + msgq = fifo.new() } return setmetatable(self, { __index = irc }) end @@ -267,6 +309,25 @@ function irc:loop() until self.conn:eof() end +function irc:msgq_loop() + while true do + self.msgq:getcv():wait() + local loop = cqueues.new() + loop:wrap(function() + while not self.msgq:empty() do + local m = self.msgq:dequeue() + self:send_chat(m.target, m.message) + cqueues.sleep(1.0) + end + end) + loop:loop() + end +end + +function irc:enqueue(target, msg) + self.msgq:enqueue{target=target, message =msg} +end + -------------------------------------------------------------------------- -- sockserver @@ -285,7 +346,7 @@ end sockserver.callbacks["/msg"] = function(self, data) local dest,msg = string.match(data or "", "^([^ ]+) (.*)") if dest then - self.ircsess:send_chat(dest, msg) + self.ircsess:enqueue(dest, msg) return "ok" end return "error: msg format" @@ -368,6 +429,10 @@ loop:wrap(function() sess:loop() end) +loop:wrap(function() + sess:msgq_loop() +end) + loop:wrap(function() srv:loop(loop) end) -- cgit v1.2.3