[Python-ideas] Add a generic async IO poller/reactor to select module
Giampaolo Rodolà
g.rodola at gmail.com
Thu May 24 20:40:31 CEST 2012
2012/5/24 Nick Coghlan <ncoghlan at gmail.com>:
> On Thu, May 24, 2012 at 10:37 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On Thu, May 24, 2012 at 9:50 PM, Giampaolo Rodolà <g.rodola at gmail.com> wrote:
>>> poller.poll serves the same purpose of asyncore.loop, yes, but this is
>>> supposed to be independent from asyncore.
>>
>> I'd actually like to see something like this pitched as a
>> "concurrent.eventloop" PEP. PEP 3153 really wasn't what I was
>> expecting after the discussions at the PyCon US 2011 language summit -
>> I was expecting "here's a common event loop all the async frameworks
>> can hook into", but instead we got something a *lot* more ambitious
>> taht tried to merge the entire IO stack for the async frameworks,
>> rather than just provide a standard way for their event loops to
>> cooperate.
>
> See the final section of my notes here:
> http://www.boredomandlaziness.org/2011/03/python-language-summit-rough-notes.html
>
> Turns out the idea of a PEP 3153 level API *was* raised at the summit,
> but I'd still like to see a competing PEP that targets the reactor
> level API directly.
>
> Cheers,
> Nick.
It's not clear to me what such a PEP should address in particular,
anyway here's a bunch of semi-random ideas.
=== Idea #1 ===
4 classes (SelectPoller, PollPoller, EpollPoller, KqueuePoller) within
concurrent.eventloop namespace all sharing the same API:
- register(fd, events, callback) # callback gets called with events as arg
- modify(fd, events)
- unregister(fd)
- call_later(timeout, callback, errback=None)
- call_every(timeout, callback, errback=None)
- poll(timeout=1.0, blocking=True)
- close()
call_later() and call_every() can return an object having cancel() and
reset() methods.
The user willing to register a new handler will do:
>>> poller.register(sock.fileno(), poller.READ | poller.WRITE, callback)
...then, in the callback:
def callback(events):
if events & poller.ERROR and not events & poller.READ:
disconnect()
else:
if events & poller.READ:
read()
if events & poller.WRITE:
write()
pros: highly customizable
cons: too low level, requires manual handling
=== Idea #2 ===
same as #1 except:
- register(fd, events)
- poll(timeout=1.0) # desn't block, return {fd:events, fd:events, ...}
=== Idea #3 ===
same as #1 except:
- register(fd, events, handler)
- poll(timeout=1.0, blocking=True)
...poll() will call handler.handle_X_event() depending on the current
event (READ, WRITE or ERROR).
An internal map such as {fd:handler, fd:handler} will be maintaned internally.
- pros: easier to use
- cons: more rigid, requires a "contract" with the handler
--- Giampaolo
http://code.google.com/p/pyftpdlib/
http://code.google.com/p/psutil/
http://code.google.com/p/pysendfile/
More information about the Python-ideas
mailing list