
Change-Id: I003177de3a9f69c71c19eb8eaa7232785e03e669 Signed-off-by: Balazs Gibizer <gibi@redhat.com>
3.4 KiB
Threading model
Eventlet
Before the Flamingo release all OpenStack services used the green thread model of threading, implemented through using the Python eventlet and greenlet libraries.
Green threads use a cooperative model of threading: thread context switches can only occur when specific eventlet or greenlet library calls are made (e.g., sleep, certain I/O calls). From the operating system's point of view, each OpenStack service runs in a single thread.
The use of green threads reduces the likelihood of race conditions,
but does not completely eliminate them. In some cases, you may need to
use the @lockutils.synchronized(...)
decorator to avoid
races.
In addition, since there is only one operating system thread, a call that blocks that main thread will block the entire process.
Yielding the thread in long-running tasks
If a code path takes a long time to execute and does not contain any methods that trigger an eventlet context switch, the long-running thread will block any pending threads.
This scenario can be avoided by adding calls to the eventlet sleep method in the long-running code path. The sleep call will trigger a context switch if there are pending threads, and using an argument of 0 will avoid introducing delays in the case that there is only a single green thread:
from eventlet import greenthread
...
greenthread.sleep(0)
In current code, time.sleep(0) does the same thing as
greenthread.sleep(0) if time module is patched through
eventlet.monkey_patch(). To be explicit, we recommend contributors use
greenthread.sleep()
instead of
time.sleep()
.
MySQL access and eventlet
There are some MySQL DB API drivers for oslo.db, like PyMySQL, MySQL-python etc. PyMySQL is the default MySQL DB API driver for oslo.db, and it works well with eventlet. MySQL-python uses an external C library for accessing the MySQL database. Since eventlet cannot use monkey-patching to intercept blocking calls in a C library, so queries to the MySQL database will block the main thread of a service.
The Diablo release contained a thread-pooling implementation that did not block, but this implementation resulted in a bug and was removed.
See this mailing list thread for a discussion of this issue, including a discussion of the impact on performance.
Native threading
Since the Flamingo release OpenStack started to transition away form
eventlet
. During this transition Nova maintains support for
running services with eventlet
while working to add support
for running services with native threading
.
To support both modes with the same codebase Nova started using the
futurist
library. In native threading mode
futurist.ThreadPoolsExecutors
are used to run concurrent
tasks and both the oslo.service and the oslo.messaging libraries are
configured to use native threads to execute tasks like periodics and RPC
message handlers.
To see how to configure and tune the native threading mode read the
/admin/concurrency
guide.