Home > OS >  Gunicorn async and threaded workers for django
Gunicorn async and threaded workers for django

Time:01-01

Async

For input/output(IO) bound we need to use async code and django is not async by default, but we can achieve this running gunicorn with the gevent worker and monkey patching:

gunicorn --worker-class=gevent --worker-connections=1000 --workers=3 main:app

Gunicorn changelog from 2014 https://docs.gunicorn.org/en/stable/2014-news.html?highlight=monkey#gevent-worker:

fix: monkey patching is now done in the worker

  1. Do i still need to monkey patch my app or it's done by default from a worker ?
  2. How did gevent achieve async functionality for my django code ?

Threads

If we have a CPU bound we need to use a gthread worker with threads:

gunicorn --workers=5 --threads=2 --worker-class=gthread main:app
  1. If we use this configuration for i/o bound, does it work? When one thread is waiting because of i/o, will the other thread be able to work?
  2. I see the point in (3) (if I'm right) because of the wait time in i/o, but if this is a CPU bound, how in our case will the second thread help us or will it only help if the core is not fully loaded by one thread and there is room for another to run?
  3. Are (3) and (4) useless because of GIL ?
    For example, 4 people sending request to server with 1 worker and 4 threads. GIL make sure that only 1 thread works. First man start processing with thread 1 and other 3 are waiting ? What are the threads for, then?

CodePudding user response:

  1. Do i still need to monkey patch my app or it's done by default from a worker ?
    No need to patch anything in your code. No need to modify codes at all.

  2. How did gevent achieve async functionality for my django code ?
    gunicorn patches everything.

  3. If we use this configuration for i/o bound, does it work? When one thread is waiting because of i/o, will the other thread be able to work?
    This configuration works for i/o bound. Threads can switch between themselves at anytime (switching controlled by ultimately the operating system), no matter whether the current thread is doing I/O or CPU-bound computation. Multiple threads can work simultaneously on multi-thread CPUs. In contrast, greenlets are more of coroutines rather than threads. If a coroutine gets blocked by I/O, it actively allows another coroutine to take control of the CPU and do non-I/O stuff.

  4. I see the point in (3) (if I'm right) because of the wait time in i/o, but if this is a CPU bound, how in our case will the second thread help us or will it only help if the core is not fully loaded by one thread and there is room for another to run?
    For a purely CPU-bounded task on a single-thread CPU, extra threads makes little sense.

  5. Are (3) and (4) useless because of GIL?
    GIL forbids your Python codes running concurrently, but gunicorn mostly uses its libraries not written in Python. You cannot run your Django codes (in Python) with multiple threads, but the I/O tasks (handled by gunicorn, not in Python) may go concurrently. If you do need CPU utilization, use multiple processes (workers=2 * CPU_THREADS 1) instead of multiple gthreads, or consider non-CPython interpreters like pypy, which is not constrained by GIL, but may not be compatible with your codes.

  • Related