asyncio in OpenStack¶
Warning
The project of replacing eventlet with trollius using aioeventlet in OpenStack is abandonned. It might done “later” when Python 2 support will be removed from OpenStack which is not going to happen in a near future.
First part (in progress): add support for trollius coroutines¶
Prepare OpenStack (Oslo Messaging) to support trollius coroutines using
yield
: explicit asynchronous programming. Eventlet is still supported,
used by default, and applications and libraries don’t need to be modified at
this point.
Already done:
Write the trollius project: port asyncio to Python 2
Stabilize trollius API
Add trollius dependency to OpenStack
Write the aioeventlet project to provide the asyncio API on top of eventlet
To do:
Stabilize aioeventlet API
Add aioeventlet dependency to OpenStack
Write an aioeventlet executor for Oslo Messaging: rewrite greenio executor to replace greenio with aioeventlet
Second part (to do): rewrite code as trollius coroutines¶
Switch from implicit asynchronous programming (eventlet using greenthreads) to
explicit asynchronous programming (trollius coroutines using yield
). Need
to modify OpenStack Common Libraries and applications. Modifications can be
done step by step, the switch will take more than 6 months.
The first application candidate is Ceilometer. The Ceilometer project is young, developers are aware of eventlet issues and like Python 3, and Ceilometer don’t rely so much on asynchronous programming: most time is spent into waiting the database anyway.
The goal is to port Ceilometer to explicit asynchronous programming during the cycle of OpenStack Kilo.
Some applications may continue to use implicit asynchronous programming. For example, nova is probably the most complex part beacuse it is and old project with a lot of legacy code, it has many drivers and the code base is large.
To do:
Ceilometer: add trollius dependency and set the trollius event loop policy to aioeventlet
Ceilometer: change Oslo Messaging executor from “eventlet” to “aioeventlet”
Redesign the service class of Oslo Incubator to support aioeventlet and/or trollius. Currently, the class is designed for eventlet. The service class is instanciated before forking, which requires hacks on eventlet to update file descriptors.
In Ceilometer and its OpenStack depedencencies: add new functions which are written with explicit asynchronous programming in mind (ex: trollius coroutines written with
yield
).Rewrite Ceilometer endpoints (RPC methods) as trollius coroutines.
Questions:
What about WSGI? aiohttp is not compatible with trollius yet.
The quantity of code which need to be ported to asynchronous programming is unknown right now.
We should be prepared to see deadlocks. OpenStack was designed for eventlet which implicitly switch on blocking operations. Critical sections may not be protected with locks, or not the right kind of lock.
For performances, blocking operations can be executed in threads. OpenStack code is probably not thread-safe, which means new kinds of race conditions. But the code executed in threads will be explicitly scheduled to be executed in a thread (with
loop.run_in_executor()
), so regressions can be easily identified.This part will take a lot of time. We may need to split it into subparts to have milestones, which is more attractive for developers.
Last part (to do): drop eventlet¶
Replace aioeventlet event loop with trollius event loop, drop aioeventlet and drop eventlet at the end.
This change will be done on applications one by one. This is no need to port all applications at once. The work will start on Ceilometer, as a follow up of the second part.
To do:
Port remaining code to trollius
Write a “trollius” executor for Oslo Messaging
Ceilometer: Add a blocking call to
loop.run_forever()
in themain()
functionCeilometer: Replace “aioeventlet” executor with “trollius” executor
Ceilometer: Use the standard trollius event loop policy
Ceilometer: drop the eventlet dependency
Questions:
Putting a blocking call to
loop.run_forever()
may need to redesign Ceilometer, this part is unclear to me right now.
Optimization, can be done later:
Oslo Messaging: watch directly the underlying file descriptor of sockets, instead of using a busy loop polling the notifier
Ceilometer: use libraries supporting directly trollius to be able to run parallel tasks (ex: send multiple requests to a database)
openstack-dev mailing list¶
[oslo] Progress of the port to Python 3 (Victor Stinner, Jan 6 2015)
[oslo] Add a new aiogreen executor for Oslo Messaging (Victor Stinner, Nov 23 2014)
[oslo] Asyncio and oslo.messaging (Mark McLoughlin, Jul 3 2014)
SQLAlchemy and asynchronous programming by Mike Bayer (author and maintainer of SQLAlchemy)
[Solum][Oslo] Next Release of oslo.messaging? (Victor Stinner, Mar 18 2014)
[solum] async / threading for python 2 and 3 (Victor Stinner, Feb 20 2014)
Asynchrounous programming: replace eventlet with asyncio (Victor Stinner, Feb 4 2014)
History of asyncio in OpenStack¶
Threads and asyncio specs:
Maybe the good one, aioeventlet project:
March 13, 2015: Joshua Harlow wrote the spec Replace eventlet + monkey-patching with ??
February 17, 2015: Joshua Harlow wrote a different spec, Sew over eventlet + patching with threads
February 5, 2015: new cross-project spec Replace eventlet with asyncio
December 3, 2014: two patches posted to requirements: Add aioeventlet dependency and Drop greenio dependency.
Novembre 23, 2014: two patches posted to Oslo Messaging: Add a new aioeventlet executor and Add an optional executor callback to dispatcher
November 19, 2014: First release of the aioeventlet project
OpenStack Kilo Summit, November 3-7, 2014, at Paris:
-
add a new greenio executor to Oslo Messaging
port eventlet to Python 3 (with monkey-patching): see the status of the eventlet port to Python 3
What should we do about oslo.messaging?: add the new greenio executor
New try with a greenio executor for Oslo Messaging:
July 29, 2014: Doug Hellmann proposed the blueprint A ‘greenio’ executor for oslo.messaging, approved by Mark McLoughlin.
July 24, 2014: Add greenio dependency merged into openstack/requirements
July 22, 2014: Patch Add a new greenio executor proposed to Oslo Messaging
July 21, 2014: Release of greenio 0.6 which is now compatible with Trollius
July 21, 2014: Release of Trollius 1.0
July 14, 2014: Patch Add a ‘greenio’ oslo.messaging executor (spec) merged into openstack/oslo-specs.
July 7, 2014: Patch Fix AMQPListener for polling with timeout merged into Oslo Messaging
July 2014: greenio executor, [openstack-dev] [oslo] Asyncio and oslo.messaging
First try with a trollius executor for Oslo Messaging:
June 20, 2014: Patch Add an optional timeout parameter to Listener.poll merged into Oslo Messaging
May 28, 2014: Meeting at OpenStack in action with Doug Hellman, Julien Danjou, Mehdi Abaakouk, Victor Stinner and Christophe to discuss the plan to port OpenStack to Python 3 and switch from eventlet to asyncio.
April 23, 2014: Patch Allow trollius 0.2 merged into openstack/requirements
March 21, 2014: Patch Replace ad-hoc coroutines with Trollius coroutines proposed to Heat. Heat coroutines are close to Trollius coroutines. Patch abandonned, need to be rewritten, maybe with aioeventlet.
February 20, 2014: The full specification of the blueprint was written: Oslo/blueprints/asyncio
February 8, 2014: Patch Add a new dependency: trollius merged into openstack/requirements
February 27, 2014: Article Use the new asyncio module and Trollius in OpenStack published
February 4, 2014: Patch Add a new asynchronous executor based on Trollius proposed to Oslo Messaging, but it was abandonned. Running a classic Trollius event loop in a dedicated thread doesn’t fit well into eventlet event loop.
First discussion around asyncio and OpenStack:
December 19, 2013: Article Why should OpenStack move to Python 3 right now? published
December 4, 2013: Blueprint Add a asyncio executor to oslo.messaging proposed by Flavio Percoco and accepted for OpenStack Icehouse by Mark McLoughlin
History of asynchronous programming in OpenStack¶
In the past, the Nova project used Tornado, then Twisted and it is now using eventlet which also became the defacto standard in OpenStack