Ask Your Question

Revision history [back]

Nova (along with a lot of other OpenStack services) uses greenthreads via eventlet. This is sometimes referred to as 'co-routines' because that's how eventlet is implemented under the hood, but that's misleading - it's possible to write code using co-routines that only does a context switch at an explicit 'yield' (asyncio in Python 3 is designed to help with this), but eventlet is not that.

I like to refer to it as co-operative multithreading, because it works in the same way as co-operative multitasking OSs from the 90s. It's true that the OS never pre-empts a thread, but a context switch can happen at any point where you call into eventlet or code that it has monkey-patched - generally sleep() and anywhere that does I/O.

The way eventlet is sometimes marketed (co-routines!), you could be forgiven for thinking that it allows you to write multithreaded code without worrying about whether it is re-entrant, but that is unfortunately not the case. You still have to worry about whether any function you call, including 3rd-party library functions, does any I/O - or could do so in the future. It's likely that in your example, db.create_context_manager() and/or rpc.create_transport() are doing I/O and must therefore be protected with a lock to make the overall function re-entrant.