Hi,

For your information, I just shared my plan to replace eventlet with
asyncio in OpenStack on the openstack-dev mailing. You can read
answers on mail-archive for example:
http://www.mail-archive.com/[email protected]/msg15652.html

Victor

----- Mail transféré -----
De: "victor stinner" <[email protected]>
À: "OpenStack" <[email protected]>
Envoyé: Mardi 4 Février 2014 14:38:39
Objet: Asynchrounous programming: replace eventlet with asyncio

Hi,

I would like to replace eventlet with asyncio in OpenStack for the
asynchronous programming. The new asyncio module has a better design
and is less "magical". It is now part of python 3.4 arguably becoming
the de-facto standard for asynchronous programming in Python world.


The asyncio module is a new module of Python 3.4 written by Guido van
Rossum as an abstraction of existing event loop (Twisted, Tornado,
eventlet, etc.). In fact, it's more than an abstraction: it has its
own event loop and can be used alone. For the background, read the
PEP:

   http://www.python.org/dev/peps/pep-3156/
   "Asynchronous IO Support Rebooted: the "asyncio" Module"

For more information on asyncio, see its documentation:

   http://docs.python.org/dev/library/asyncio.html

The asyncio module is also known as "Tulip" which is third-party
project written for Python 3.3. Tulip was written first and then it
was integrated in Python 3.4.

   http://code.google.com/p/tulip/

The main difference between eventlet and asyncio is that context
switching between two concurrent tasks is explicit. When a task
"blocks"  (ex: wait for an event), it should use the "yield from"
syntax which will switch to the next task: it's similar to
"greenlet.switch" in eventlet. So it becomes obvious which parts of
the code do switch and which don't. With eventlet, you have to read
the source code of a function before calling it to check if it may
call greenlet.switch() or not, and so debugging is more difficult. Or
worse, the function may switch in a new version of a module, you won't
notice the change.

The asyncio module handles various kind of events: sockets, pipes,
subprocesses, UNIX signals, etc. All these things are handled in a
single event loop. You can uses an "exector" to run a blocking task in
a pool of thread. There is a "low-level" API using transports and
protocols, similar to Twisted transports and protocols. But there is
also a "high-level" API using streams, which gives a syntax close to
eventlet (except that you have to add "yield from"). See an example to
send an HTTP request and print received HTTP headers, the "yield from
reader.readline()" instruction "blocks" until it gets a full line:

   http://docs.python.org/dev/library/asyncio-stream.html#example


The problem is that the asyncio module was written for Python 3.3,
whereas OpenStack is not fully Python 3 compatible (yet). To easy the
transition I have ported asyncio on Python 2, it's the new Trollis
project which supports Python 2.6-3.4:

   https://bitbucket.org/enovance/trollius

The Trollius API is the same than asyncio, the main difference is the
syntax in coroutines: "yield from task" must be written "yield task",
and "return value" must be written "raise Return(value)".



The first step to move from eventlet to asyncio is a new executor
using Trollius in Olso Messaging:

  https://wiki.openstack.org/wiki/Oslo/blueprints/asyncio
  https://review.openstack.org/#/c/70948


The transition from eventlet to asyncio can be done step by step.
Thanks to the greenio project, asyncio can reuse the greenlet event
loop (and so run in the main thread). So asyncio and eventlet become
"compatible". While asyncio can also run its own event loop in a
separated thread.

If eventlet is completely replaced with asyncio in a project, greenio
can be dropped, and asyncio event loop can be run its own event loop
in the main thread.

When OpenStack will be compatible with Python 3.3, it will be possible
to use the builtin asyncio module of Python 3.4 directly instead of
Trollus. Since "yield from" is incompatible with Python 2, some parts
of the code may need to have two versions (one for Python 2, one for
Python 3) if we want to use the "Python 3 flavor" of asyncio... or
Python 2 support might be simplify dropped.

Victor

Reply via email to