Use new asyncio based events
This commit is contained in:
parent
69dcd53937
commit
30c81c1c4b
3 changed files with 71 additions and 12 deletions
|
|
@ -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 ####################################################
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue