poezio/poezio/asyncio.py
2017-11-12 15:03:09 +01:00

43 lines
1.3 KiB
Python

"""
A module that monkey patches the standard asyncio module to add an
idle_call() method to the main loop. This method is used to execute a
callback whenever the loop is not busy handling anything else. This means
that it is a callback with lower priority than IO, timer, or even
call_soon() ones. These callback are called only once each.
"""
import asyncio
import functools
import collections
from asyncio import events
import slixmpp
def monkey_patch_asyncio_slixmpp():
def idle_call(self, callback):
if asyncio.iscoroutinefunction(callback):
raise TypeError("coroutines cannot be used with idle_call()")
handle = events.Handle(callback, [], self)
self._idle.append(handle)
def my_run_once(self):
if self._idle:
self._ready.append(events.Handle(lambda: None, (), self))
real_run_once(self)
if self._idle:
handle = self._idle.popleft()
handle._run()
cls = asyncio.get_event_loop().__class__
cls._idle = collections.deque()
cls.idle_call = idle_call
real_run_once = cls._run_once
cls._run_once = my_run_once
spawn_event = slixmpp.xmlstream.XMLStream._spawn_event
def patchy(self, xml):
self.loop.idle_call(functools.partial(spawn_event, self, xml))
slixmpp.xmlstream.XMLStream._spawn_event = patchy