Use new asyncio based events

This commit is contained in:
nemunaire 2017-09-01 20:39:40 +02:00
commit 30c81c1c4b
3 changed files with 71 additions and 12 deletions

View file

@ -37,10 +37,8 @@ def load(context):
chan = sayon["channel"]
context.send_response(srv, Response(txt, chan))
d = datetime(yrn, 1, 1, 0, 0, 0, 0,
timezone.utc) - datetime.now(timezone.utc)
context.add_event(ModuleEvent(interval=0, offset=d.total_seconds(),
call=bonneannee))
context.call_at(datetime(yrn, 1, 1, 0, 0, 0, 0, timezone.utc),
bonneannee)
# MODULE INTERFACE ####################################################

View file

@ -64,6 +64,13 @@ class Bot(threading.Thread):
#
self.loop = loop if loop is not None else asyncio.get_event_loop()
# Those events are used to ensure there is always one event in the next 24h, else overflow can occurs on loop timeout
def event_sentinel(offset=43210):
logger.debug("Defining new event sentinelle in %ss", 43210 + offset)
self.loop.call_later(43210 + offset, event_sentinel)
event_sentinel(0)
event_sentinel(43210)
# External IP for accessing this bot
import ipaddress
self.ip = ipaddress.ip_address(ip)
@ -242,6 +249,25 @@ class Bot(threading.Thread):
# Events methods
@asyncio.coroutine
def _call_at(self, when, *args, **kwargs):
@asyncio.coroutine
def _add_event():
return self.loop.call_at(when, *args, **kwargs)
future = yield from asyncio.run_coroutine_threadsafe(_add_event(), loop=self.loop)
logger.debug("New event registered, scheduled in %ss", when - self.loop.time())
return future.result()
def call_at(self, when, *args, **kwargs):
delay = (when - datetime.now(timezone.utc)).total_seconds()
return self._call_at(self.loop.time() + delay, *args, **kwargs)
def call_delay(self, delay, *args, **kwargs):
return self._call_at(self.loop.time() + delay, *args, **kwargs)
def add_event(self, evt):
"""Register an event and return its identifiant for futur update

View file

@ -16,6 +16,13 @@
import asyncio
class _TinyEvent:
def __init__(self, handle):
self.handle = handle
class _FakeHandle:
def __init__(self, true_handle, callback):
@ -27,9 +34,10 @@ class _FakeHandle:
if self.callback:
return self.callback()
class _ModuleContext:
def __init__(self, module=None):
def __init__(self, module=None, knodes=None):
self.module = module
if module is not None:
@ -43,6 +51,7 @@ class _ModuleContext:
from nemubot.config.module import Module
self.config = Module(self.module_name)
self._knodes = knodes
def load_data(self):
@ -65,8 +74,13 @@ class _ModuleContext:
return None
def set_knodes(self, knodes):
self._knodes = knodes
def add_event(self, evt):
return self.events.append(evt)
self.events.append(evt)
return evt
def del_event(self, evt):
return self.events.remove(evt)
@ -88,6 +102,15 @@ class _ModuleContext:
self._data = self.load_data()
return self._data
@data.setter
def data(self, data):
self._data = data
return self._data
@data.deleter
def data(self):
self._data = None
def unload(self):
"""Perform actions for unloading the module"""
@ -97,7 +120,7 @@ class _ModuleContext:
self.del_hook(h, *s)
# Remove registered events
for evt, eid, module_src in self.events:
for evt in self.events:
self.del_event(evt)
self.save()
@ -124,7 +147,7 @@ class ModuleContext(_ModuleContext):
def load_data(self):
return self.context.datastore.load(self.module_name)
return self.context.datastore.load(self.module_name, self._knodes)
def save(self):
self.context.datastore.save(self.module_name, self.data)
@ -147,20 +170,32 @@ class ModuleContext(_ModuleContext):
yield from self.context.treater.treat_msg(msg)
def add_event(self, evt):
def _add_event(self, evt, call_add, *args, **kwargs):
if evt in self.events:
return None
def _cancel_event():
logger.debug("Cancel event")
self.module.logger.debug("Cancel event")
evt.handle = None
return super().del_event(evt)
return super(ModuleContext, self).del_event(evt)
hd = self.context.add_event(evt)
hd = call_add(*args, **kwargs)
evt.handle = _FakeHandle(hd, _cancel_event)
return super().add_event(evt)
def add_event(self, evt):
return self._add_event(evt, self.context.add_event, evt)
def call_at(self, *args, **kwargs):
evt = _TinyEvent(None)
return self._add_event(evt, self.context.call_at, *args, **kwargs)
def call_later(self, *args, **kwargs):
evt = _TinyEvent(None)
return self._add_event(evt, self.context.call_later, *args, **kwargs)
def del_event(self, evt):
# Call to super().del_event is done in the _FakeHandle.cancel
return evt.handle.cancel()