def add_event(self, loop, instance, fn):
"""
Wraps the given function in a corutine which calls it every N seconds
:param loop: The event loop (cls._loop)
:param instance: The instantiated class
:param fn: The function to be called
:return: None
"""
# Verify function signature
argspec = inspect.getfullargspec(fn)
n_args = len(argspec.args) - 1 if 'self' in argspec.args else len(argspec.args)
n_required_args = n_args - (len(argspec.defaults) if argspec.defaults else 0)
assert n_required_args == 0, 'Functions decorated with @Periodic cannot have any required parameters.'
@asyncio.coroutine
def periodic_fn():
# If coroutine yield from else call normally
is_coroutine = asyncio.iscoroutinefunction(fn)
while True:
last_exec = time.time()
(yield from fn()) if is_coroutine else fn()
yield from asyncio.sleep(max(0, self.time + last_exec - time.time()))
super().add_event(loop, instance, periodic_fn())
评论列表
文章目录