From cb94fa9ae45b521b3189a215532516ec5603a217 Mon Sep 17 00:00:00 2001 From: jesopo Date: Fri, 12 Oct 2018 17:54:15 +0100 Subject: [PATCH] Add TimersContext, to be able to purge timers when modules are unloaded --- src/ModuleManager.py | 11 ++++++++--- src/Timers.py | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/ModuleManager.py b/src/ModuleManager.py index 0a9d0d67..6b097815 100644 --- a/src/ModuleManager.py +++ b/src/ModuleManager.py @@ -22,16 +22,18 @@ class ModuleNotLoadedWarning(ModuleWarning): pass class BaseModule(object): - def __init__(self, bot, events, exports): + def __init__(self, bot, events, exports, timers): self.bot = bot self.events = events self.exports = exports + self.timers = timers class ModuleManager(object): - def __init__(self, events, exports, config, log, directory): + def __init__(self, events, exports, timers, config, log, directory): self.events = events self.exports = exports self.config = config + self.timers = timers self.log = log self.directory = directory @@ -84,7 +86,9 @@ class ModuleManager(object): context = str(uuid.uuid4()) context_events = self.events.new_context(context) context_exports = self.exports.new_context(context) - module_object = module.Module(bot, context_events, context_exports) + context_timers = self.timers.new_context(context) + module_object = module.Module(bot, context_events, context_exports, + context_timers) if not hasattr(module_object, "_name"): module_object._name = name.title() @@ -144,6 +148,7 @@ class ModuleManager(object): context = module._context self.events.purge_context(context) self.exports.purge_context(context) + self.timers.purge_context(context) del sys.modules[self._import_name(name)] references = sys.getrefcount(module) diff --git a/src/Timers.py b/src/Timers.py index 7da23f01..8f852816 100644 --- a/src/Timers.py +++ b/src/Timers.py @@ -27,12 +27,27 @@ class Timer(object): def done(self): return self._done +class TimersContext(object): + def __init__(self, parent, context): + self._parent = parent + self.context = context + def add(self, name, delay, next_due=None, **kwargs): + self._parent._add(self.context, name, delay, next_due, None, False, + kwargs) + def add_persistent(self, name, delay, next_due=None, **kwargs): + self._parent._add(self.context, name, delay, next_due, None, True, + kwargs) + class Timers(object): def __init__(self, database, events, log): self.database = database self.events = events self.log = log self.timers = [] + self.context_timers = {} + + def new_context(self, context): + return TimersContext(self, context) def setup(self, timers): for name, timer in timers: @@ -49,15 +64,21 @@ class Timers(object): self.database.bot_settings.delete("timer-%s" % timer.id) def add(self, name, delay, next_due=None, **kwargs): - self._add(name, delay, next_due, None, False, kwargs) + self._add(None, name, delay, next_due, None, False, kwargs) def add_persistent(self, name, delay, next_due=None, **kwargs): - self._add(name, delay, next_due, None, True, kwargs) - def _add(self, name, delay, next_due, id, persist, kwargs): + self._add(None, name, delay, next_due, None, True, kwargs) + def _add(self, context, name, delay, next_due, id, persist, kwargs): id = id or uuid.uuid4().hex timer = Timer(id, name, delay, next_due, kwargs) if persist: self._persist(timer) - self.timers.append(timer) + + if context and not persist: + if not context in self.context_timers: + self.context_timers[context] = [] + self.context_timers[context].append(timer) + else: + self.timers.append(timer) def next(self): times = filter(None, [timer.time_left() for timer in self.timers]) @@ -65,11 +86,18 @@ class Timers(object): return None return max(min(times), 0) + def get_timers(self): + return self.timers + sum(self.context_timers.values(), []) + def call(self): - for timer in self.timers[:]: + for timer in self.get_timers(): if timer.due(): timer.finish() self.events.on("timer.%s" % timer.name).call(timer=timer, **timer.kwargs) if timer.done(): self._remove(timer) + + def purge_context(self, context): + if context in self.context_timers: + del self.context_timers[context]