diff options
author | Florent Le Coz <louiz@louiz.org> | 2015-01-03 05:55:17 +0100 |
---|---|---|
committer | Florent Le Coz <louiz@louiz.org> | 2015-01-03 06:08:03 +0100 |
commit | 47fbd4cead2e881b0250dd5f978caf64c6a5952c (patch) | |
tree | ce556dce5c575c3a1d7067ba6196ba0b68d72265 /slixmpp/xmlstream/asyncio.py | |
parent | 1b9b4199e8ecfdc379a34b74dd9b3b197365d74a (diff) | |
download | slixmpp-47fbd4cead2e881b0250dd5f978caf64c6a5952c.tar.gz slixmpp-47fbd4cead2e881b0250dd5f978caf64c6a5952c.tar.bz2 slixmpp-47fbd4cead2e881b0250dd5f978caf64c6a5952c.tar.xz slixmpp-47fbd4cead2e881b0250dd5f978caf64c6a5952c.zip |
Delay the handling of stanza for when the process is not busy
We use some dirty monkey-patching to add a idle_call() function to the
asyncio module. We then use that method to handle each received stanza only
when the event loop is not busy with some other IO (mainly, the standard
input)
Diffstat (limited to 'slixmpp/xmlstream/asyncio.py')
-rw-r--r-- | slixmpp/xmlstream/asyncio.py | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/slixmpp/xmlstream/asyncio.py b/slixmpp/xmlstream/asyncio.py new file mode 100644 index 00000000..52610d01 --- /dev/null +++ b/slixmpp/xmlstream/asyncio.py @@ -0,0 +1,32 @@ +""" +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 +from asyncio import tasks, events + +def idle_call(self, callback): + if tasks.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.pop(0) + handle._run() + +cls = asyncio.get_event_loop().__class__ + +cls._idle = [] +cls.idle_call = idle_call +real_run_once = cls._run_once +cls._run_once = my_run_once + |