transient timers shouldn't use the event system

This commit is contained in:
jesopo 2019-10-08 13:49:43 +01:00
parent 4c02c7c86a
commit 7a5edccb98
7 changed files with 56 additions and 52 deletions

View file

@ -41,9 +41,9 @@ class CoinParseException(Exception):
class Module(ModuleManager.BaseModule): class Module(ModuleManager.BaseModule):
def on_load(self): def on_load(self):
self.timers.add("coin-interest", INTEREST_INTERVAL, self.timers.add("coin-interest", self._interest, INTEREST_INTERVAL,
time.time()+self._until_next_hour()) time.time()+self._until_next_hour())
self.timers.add("coin-lottery", LOTTERY_INTERVAL, self.timers.add("coin-lottery", self._lottery, LOTTERY_INTERVAL,
time.time()+self._until_next_6_hour()) time.time()+self._until_next_6_hour())
def _until_next_hour(self, now=None): def _until_next_hour(self, now=None):
@ -440,8 +440,7 @@ class Module(ModuleManager.BaseModule):
"%s loses %s" % (choice, event["user"].nickname, "%s loses %s" % (choice, event["user"].nickname,
str(coin_losses))) str(coin_losses)))
@utils.hook("timer.coin-interest") def _interest(self, timer):
def interest(self, event):
for server in self.bot.servers.values(): for server in self.bot.servers.values():
if not server.get_setting("coin-interest", False): if not server.get_setting("coin-interest", False):
continue continue
@ -456,7 +455,7 @@ class Module(ModuleManager.BaseModule):
interest = round(coins*interest_rate, 2) interest = round(coins*interest_rate, 2)
server.set_user_setting(nickname, "coins", server.set_user_setting(nickname, "coins",
self._coin_str(coins+interest)) self._coin_str(coins+interest))
event["timer"].redo() timer.redo()
@utils.hook("received.command.lotterybuy", authenticated=True) @utils.hook("received.command.lotterybuy", authenticated=True)
def lottery_buy(self, event): def lottery_buy(self, event):
@ -539,8 +538,7 @@ class Module(ModuleManager.BaseModule):
else: else:
event["stderr"].write("There have been no lottery winners!") event["stderr"].write("There have been no lottery winners!")
@utils.hook("timer.coin-lottery") def _lottery(self, timer):
def lottery(self, event):
for server in self.bot.servers.values(): for server in self.bot.servers.values():
lottery = server.get_setting("lottery", {}) lottery = server.get_setting("lottery", {})
if lottery: if lottery:
@ -561,4 +559,4 @@ class Module(ModuleManager.BaseModule):
server.set_setting("lottery-winner", user.nickname) server.set_setting("lottery-winner", user.nickname)
user.send_notice("You won %s in the lottery! you now have %s coins" user.send_notice("You won %s in the lottery! you now have %s coins"
% (self._coin_str(winnings), self._coin_str(new_coins))) % (self._coin_str(winnings), self._coin_str(new_coins)))
event["timer"].redo() timer.redo()

View file

@ -10,11 +10,10 @@ class Module(ModuleManager.BaseModule):
until_next_hour = 60-now.second until_next_hour = 60-now.second
until_next_hour += ((60-(now.minute+1))*60) until_next_hour += ((60-(now.minute+1))*60)
self.timers.add("database-backup", BACKUP_INTERVAL, self.timers.add("database-backup", self._backup, BACKUP_INTERVAL,
time.time()+until_next_hour) time.time()+until_next_hour)
@utils.hook("timer.database-backup") def _backup(self, timer):
def backup(self, event):
location = self.bot.database.location location = self.bot.database.location
files = glob.glob("%s.*" % location) files = glob.glob("%s.*" % location)
files = sorted(files) files = sorted(files)
@ -26,4 +25,4 @@ class Module(ModuleManager.BaseModule):
backup_file = "%s.%s" % (location, suffix) backup_file = "%s.%s" % (location, suffix)
shutil.copy2(location, backup_file) shutil.copy2(location, backup_file)
event["timer"].redo() timer.repo()

View file

@ -28,12 +28,12 @@ class Module(ModuleManager.BaseModule):
if delay == 0: if delay == 0:
self._rejoin(event["server"], event["channel"].name) self._rejoin(event["server"], event["channel"].name)
else: else:
self.timers.add("kick-rejoin", delay, server=event["server"], self.timers.add("kick-rejoin",
channel_name=event["channel"].name) self._timer(event["server"], event["channel"].name),
delay)
@utils.hook("timer.kick-rejoin") def _timer(self, server, channel_name):
def timer(self, event): return lambda timer: self._rejoin(server, channel_name)
self._rejoin(event["server"], event["channel_name"])
def _rejoin(self, server, channel_name): def _rejoin(self, server, channel_name):
server.send_join(channel_name) server.send_join(channel_name)

View file

@ -7,7 +7,8 @@ class Module(ModuleManager.BaseModule):
if "MONITOR" in server.isupport: if "MONITOR" in server.isupport:
server.send_raw("MONITOR + %s" % target_nick) server.send_raw("MONITOR + %s" % target_nick)
else: else:
self.timers.add("ison-check", 30, server=server) self.timers.add("ison-check", self._ison_check, 30,
server=server)
@utils.hook("received.376") @utils.hook("received.376")
def end_of_motd(self, event): def end_of_motd(self, event):
@ -31,13 +32,12 @@ class Module(ModuleManager.BaseModule):
if event["server"].irc_lower(target_nick) in nicks: if event["server"].irc_lower(target_nick) in nicks:
event["server"].send_nick(target_nick) event["server"].send_nick(target_nick)
@utils.hook("timer.ison-check") def _ison_check(self, timer):
def ison_check(self, event): server = timer.kwargs["server"]
target_nick = event["server"].connection_params.nickname target_nick = server.connection_params.nickname
if not event["server"].irc_equals( if not server.irc_equals(server.nickname, target_nick):
event["server"].nickname, target_nick): server.send_raw("ISON %s" % target_nick)
event["server"].send_raw("ISON %s" % target_nick) timer.redo()
event["timer"].redo()
@utils.hook("received.303") @utils.hook("received.303")
def ison_response(self, event): def ison_response(self, event):

View file

@ -14,8 +14,8 @@ RSS_INTERVAL = 60 # 1 minute
class Module(ModuleManager.BaseModule): class Module(ModuleManager.BaseModule):
_name = "RSS" _name = "RSS"
def on_load(self): def on_load(self):
self.timers.add("rss", self.bot.get_setting("rss-interval", self.timers.add("rss-feeds", self._timer,
RSS_INTERVAL)) self.bot.get_setting("rss-interval", RSS_INTERVAL))
def _format_entry(self, server, feed_title, entry, shorten): def _format_entry(self, server, feed_title, entry, shorten):
title = entry["title"] title = entry["title"]
@ -32,13 +32,11 @@ class Module(ModuleManager.BaseModule):
return "%s%s%s%s" % (feed_title_str, title, author, link) return "%s%s%s%s" % (feed_title_str, title, author, link)
def _timer(self, timer):
@utils.hook("timer.rss")
def timer(self, event):
start_time = time.monotonic() start_time = time.monotonic()
self.log.trace("Polling RSS feeds") self.log.trace("Polling RSS feeds")
event["timer"].redo() timer.redo()
hook_settings = self.bot.database.channel_settings.find_by_setting( hook_settings = self.bot.database.channel_settings.find_by_setting(
"rss-hooks") "rss-hooks")
hooks = {} hooks = {}

View file

@ -1,7 +1,7 @@
import enum, queue, os, queue, select, socket, sys, threading, time, traceback import enum, queue, os, queue, select, socket, sys, threading, time, traceback
import typing, uuid import typing, uuid
from src import EventManager, Exports, IRCServer, Logging, ModuleManager from src import EventManager, Exports, IRCServer, Logging, ModuleManager
from src import PollHook, Socket, utils from src import PollHook, Socket, Timers, utils
VERSION = "v1.11.1" VERSION = "v1.11.1"
SOURCE = "https://git.io/bitbot" SOURCE = "https://git.io/bitbot"
@ -83,8 +83,6 @@ class Bot(object):
self._poll_timeouts.append(ListLambdaPollHook( self._poll_timeouts.append(ListLambdaPollHook(
lambda: self.servers.values(), self._throttle_timeout)) lambda: self.servers.values(), self._throttle_timeout))
self._events.on("timer.reconnect").hook(self._timed_reconnect)
def _throttle_timeout(self, server: IRCServer.Server): def _throttle_timeout(self, server: IRCServer.Server):
if server.socket.waiting_throttled_send(): if server.socket.waiting_throttled_send():
return server.socket.send_throttle_timeout() return server.socket.send_throttle_timeout()
@ -216,12 +214,13 @@ class Bot(object):
del self.servers[server.fileno()] del self.servers[server.fileno()]
self._trigger_both() self._trigger_both()
def _timed_reconnect(self, event: EventManager.Event): def _timed_reconnect(self, timer: Timers.Timer):
if not self.reconnect(event["server_id"], server_id = timer.kwargs["server_id"]
event.get("connection_params", None)): params = timer.kwargs.get("connection_params", None)
event["timer"].redo() if not self.reconnect(server_id, params):
timer.redo()
else: else:
del self.reconnections[event["server_id"]] del self.reconnections[server_id]
def reconnect(self, server_id: int, connection_params: typing.Optional[ def reconnect(self, server_id: int, connection_params: typing.Optional[
utils.irc.IRCConnectionParameters]=None) -> bool: utils.irc.IRCConnectionParameters]=None) -> bool:
args = {} # type: typing.Dict[str, str] args = {} # type: typing.Dict[str, str]
@ -395,8 +394,8 @@ class Bot(object):
if not self.get_server_by_id(server.id): if not self.get_server_by_id(server.id):
reconnect_delay = self.config.get("reconnect-delay", 10) reconnect_delay = self.config.get("reconnect-delay", 10)
timer = self._timers.add("reconnect", reconnect_delay, self.timers.add("timed-reconnect", self._timed_reconnect,
server_id=server.id) reconnect_delay, server_id=server.id)
self.reconnections[server.id] = timer self.reconnections[server.id] = timer
self.log.warn( self.log.warn(

View file

@ -1,9 +1,12 @@
import time, typing, uuid import time, typing, uuid
from src import Database, EventManager, Logging, PollHook from src import Database, EventManager, Logging, PollHook
T_CALLBACK = typing.Callable[["Timer"], None]
class Timer(object): class Timer(object):
def __init__(self, id: str, context: typing.Optional[str], name: str, def __init__(self, id: str, context: typing.Optional[str], name: str,
delay: float, next_due: typing.Optional[float], kwargs: dict): delay: float, next_due: typing.Optional[float], kwargs: dict,
callback: T_CALLBACK):
self.id = id self.id = id
self.context = context self.context = context
self.name = name self.name = name
@ -13,6 +16,7 @@ class Timer(object):
else: else:
self.set_next_due() self.set_next_due()
self.kwargs = kwargs self.kwargs = kwargs
self.callback = callback
self._done = False self._done = False
def set_next_due(self): def set_next_due(self):
@ -64,17 +68,24 @@ class Timers(PollHook.PollHook):
self.timers.remove(timer) self.timers.remove(timer)
self.database.bot_settings.delete("timer-%s" % timer.id) self.database.bot_settings.delete("timer-%s" % timer.id)
def add(self, name: str, delay: float, next_due: float=None, **kwargs def add(self, name: str, callback: T_CALLBACK, delay: float,
) -> Timer: next_due: float=None, **kwargs) -> Timer:
return self._add(None, name, delay, next_due, None, False, kwargs) return self._add(None, name, delay, next_due, None, False, kwargs,
callback=callback)
def add_persistent(self, name: str, delay: float, next_due: float=None, def add_persistent(self, name: str, delay: float, next_due: float=None,
**kwargs) -> Timer: **kwargs) -> Timer:
return self._add(None, name, delay, next_due, None, True, kwargs) return self._add(None, name, delay, next_due, None, True, kwargs)
def _add(self, context: typing.Optional[str], name: str, delay: float, def _add(self, context: typing.Optional[str], name: str, delay: float,
next_due: typing.Optional[float], id: typing.Optional[str], next_due: typing.Optional[float], id: typing.Optional[str],
persist: bool, kwargs: dict) -> Timer: persist: bool, kwargs: dict, callback: T_CALLBACK=None) -> Timer:
id = id or str(uuid.uuid4()) id = id or str(uuid.uuid4())
timer = Timer(id, context, name, delay, next_due, kwargs)
if not callback:
callback = lambda timer: self.events.on("timer.%s" % name).call(
timer=timer, **kwargs)
timer = Timer(id, context, name, delay, next_due, kwargs,
callback=callback)
if persist: if persist:
self._persist(timer) self._persist(timer)
@ -110,8 +121,7 @@ class Timers(PollHook.PollHook):
for timer in self.get_timers(): for timer in self.get_timers():
if timer.due(): if timer.due():
timer.finish() timer.finish()
self.events.on("timer.%s" % timer.name).call(timer=timer, timer.callback(timer)
**timer.kwargs)
if timer.done(): if timer.done():
self._remove(timer) self._remove(timer)
@ -123,10 +133,10 @@ class TimersContext(object):
def __init__(self, parent: Timers, context: str): def __init__(self, parent: Timers, context: str):
self._parent = parent self._parent = parent
self.context = context self.context = context
def add(self, name: str, delay: float, next_due: float=None, def add(self, name: str, callback: T_CALLBACK, delay: float,
**kwargs) -> Timer: next_due: float=None, **kwargs) -> Timer:
return self._parent._add(self.context, name, delay, next_due, None, return self._parent._add(self.context, name, delay, next_due, None,
False, kwargs) False, kwargs, callback=callback)
def add_persistent(self, name: str, delay: float, next_due: float=None, def add_persistent(self, name: str, delay: float, next_due: float=None,
**kwargs) -> Timer: **kwargs) -> Timer:
return self._parent._add(None, name, delay, next_due, None, True, return self._parent._add(None, name, delay, next_due, None, True,