2012-12-12 20:35:17 -05:00
|
|
|
|
PEP: 3156
|
|
|
|
|
Title: Asynchronous IO Support Rebooted
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
|
|
|
|
Author: Guido van Rossum <guido@python.org>
|
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 12-Dec-2012
|
|
|
|
|
Post-History: TBD
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
A concrete proposal for asynchronous I/O in Python 3, starting with
|
|
|
|
|
Python 3.3. Consider this the concrete proposal that is missing from
|
|
|
|
|
PEP 3153. The proposal includes a pluggable event loop API, transport
|
|
|
|
|
and protocol abstractions similar to those in Twisted, and a
|
|
|
|
|
higher-level scheduler based on yield-from (PEP 380). A reference
|
|
|
|
|
implementation is in the works under the code name tulip.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Introduction
|
|
|
|
|
============
|
|
|
|
|
|
2012-12-12 21:30:32 -05:00
|
|
|
|
The event loop is the place where most interoperability occurs. It
|
|
|
|
|
should be easy for (Python 3.3 ports of) frameworks like Twisted,
|
|
|
|
|
Tornado, or ZeroMQ to either adapt the default event loop
|
|
|
|
|
implementation to their needs using a lightweight wrapper or proxy, or
|
|
|
|
|
to replace the default event loop implementation with an adaptation of
|
|
|
|
|
their own event loop implementation. (Some frameworks, like Twisted,
|
|
|
|
|
have multiple event loop implementations. This should not be a
|
|
|
|
|
problem since these all have the same interface.)
|
|
|
|
|
|
|
|
|
|
It should even be possible for two different third-party frameworks to
|
|
|
|
|
interoperate, either by sharing the default event loop implementation
|
|
|
|
|
(each using its own adapter), or by sharing the event loop
|
|
|
|
|
implementation of either framework. In the latter case two levels of
|
|
|
|
|
adaptation would occur (from framework A's event loop to the standard
|
|
|
|
|
event loop interface, and from there to framework B's event loop).
|
|
|
|
|
Which event loop implementation is used should be under control of the
|
|
|
|
|
main program (though a default policy for event loop selection is
|
|
|
|
|
provided).
|
|
|
|
|
|
|
|
|
|
Thus, two separate APIs are defined:
|
|
|
|
|
|
|
|
|
|
- getting and setting the current event loop object
|
|
|
|
|
- the interface of a conforming event loop and its minimum guarantees
|
|
|
|
|
|
|
|
|
|
An event loop implementation may provide additional methods and
|
|
|
|
|
guarantees.
|
|
|
|
|
|
|
|
|
|
The event loop interface does not depend on yield-from. Rather, it
|
|
|
|
|
uses a combination of callbacks, additional interfaces (transports and
|
|
|
|
|
protocols), and Futures. The latter are similar to those defined in
|
|
|
|
|
PEP 3148, but have a different implementation and are not tied to
|
|
|
|
|
threads. In particular, they have no wait() method; the user is
|
|
|
|
|
expected to use callbacks.
|
|
|
|
|
|
|
|
|
|
For users (like myself) who don't like using callbacks, a scheduler is
|
|
|
|
|
provided for writing asynchronous I/O code as coroutines using the PEP
|
|
|
|
|
380 yield-from expressions. The scheduler is not pluggable;
|
|
|
|
|
pluggability occurs at the event loop level, and the scheduler should
|
|
|
|
|
work with any conforming event loop implementation.
|
|
|
|
|
|
|
|
|
|
For interoperability between code written using coroutines and other
|
|
|
|
|
async frameworks, the scheduler has a Task class that behaves like a
|
|
|
|
|
Future. A framework that interoperates at the event loop level can
|
|
|
|
|
wait for a Future to complete by adding a callback to the Future.
|
|
|
|
|
Likewise, the scheduler offers an operation to suspend a coroutine
|
|
|
|
|
until a callback is called.
|
|
|
|
|
|
|
|
|
|
Limited interoperability with threads is provided by the event loop
|
|
|
|
|
interface; there is an API to submit a function to an executor (see
|
|
|
|
|
PEP 3148) which returns a Future that is compatible with the event
|
|
|
|
|
loop.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Non-goals
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
Interoperability with systems like Stackless Python or
|
|
|
|
|
greenlets/gevent is not a goal of this PEP.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Specification
|
|
|
|
|
=============
|
|
|
|
|
|
|
|
|
|
TBD.
|
2012-12-12 20:35:17 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Acknowledgments
|
|
|
|
|
===============
|
|
|
|
|
|
|
|
|
|
Apart from PEP 3153, influences include PEP 380 and Greg Ewing's
|
|
|
|
|
tutorial for yield-from, Twisted, Tornado, ZeroMQ, pyftpdlib, tulip
|
|
|
|
|
(the author's attempts at synthesis of all these), wattle (Steve
|
|
|
|
|
Dower's counter-proposal), numerous discussions on python-ideas from
|
|
|
|
|
September through December 2012, a Skype session with Steve Dower and
|
2012-12-12 21:30:32 -05:00
|
|
|
|
Dino Viehland, email exchanges with Ben Darnell, an audience with
|
|
|
|
|
Niels Provos (original author of libevent), and two in-person meetings
|
|
|
|
|
with several Twisted developers, including Glyph, Brian Warner, David
|
|
|
|
|
Reid, and Duncan McGreggor.
|
2012-12-12 20:35:17 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
|
|
|
|
fill-column: 70
|
|
|
|
|
coding: utf-8
|
|
|
|
|
End:
|