emmett-framework / granian

A Rust HTTP server for Python applications
BSD 3-Clause "New" or "Revised" License
2.77k stars 83 forks source link

Is it possible to have gevent support? #380

Closed vooon closed 1 month ago

vooon commented 2 months ago

FYI I run most of OpenStack API services under Granian, but cannot run nova-api:

Command:

ExecStart=/usr/bin/granian /etc/granian/openstack_nova_api.py:application \
    --host 192.168.50.91 \
    --port 18774 \
    --interface wsgi \
    --workers 8 \
    --threads 1 \
    --log-level debug

WSGI file (i kept lock like in original pbr's one):

import sys
import threading
from nova.api.openstack.compute.wsgi import init_application

application = None
app_lock = threading.Lock()

with app_lock:
    # remove granian options
    sys.argv = [sys.argv[0]]
    sys.argv += ["--config-file=/etc/nova/nova.conf", "--log-file=nova-api.log"]

    if application is None:
        application = init_application()
Aug 16 11:15:18 p091 systemd[1]: Started Nova - openstack-nova-api.
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Websockets are not supported on WSGI
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Starting granian (main PID: 1182905)
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Listening at: http://192.168.50.91:18774
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-1 with pid: 1182908
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-2 with pid: 1182910
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-3 with pid: 1182912
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-4 with pid: 1182914
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-5 with pid: 1182916
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-6 with pid: 1182918
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-7 with pid: 1182920
Aug 16 11:15:18 p091 granian[1182905]: [INFO] Spawning worker-8 with pid: 1182922
Aug 16 11:15:19 p091 granian[1182914]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182912]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182920]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182918]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182908]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182910]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182922]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:19 p091 granian[1182916]: Modules with known eventlet monkey patching issues were imported prior to eventlet monkey patching: urllib3. This warning can usually be ignored if the caller is only importing and not executing nova code.
Aug 16 11:15:23 p091 granian[1182908]: [INFO] Started worker-1
Aug 16 11:15:23 p091 granian[1182920]: [INFO] Started worker-7
Aug 16 11:15:24 p091 granian[1182918]: [INFO] Started worker-6
Aug 16 11:15:24 p091 granian[1182912]: [INFO] Started worker-3
Aug 16 11:15:24 p091 granian[1182916]: [INFO] Started worker-5
Aug 16 11:15:24 p091 granian[1182910]: [INFO] Started worker-2
Aug 16 11:15:24 p091 granian[1182914]: [INFO] Started worker-4
Aug 16 11:15:24 p091 granian[1182922]: [INFO] Started worker-8
Aug 16 11:18:48 p091 granian[1182914]: Traceback (most recent call last):
Aug 16 11:18:48 p091 granian[1182914]:   File "/usr/lib/python3.9/site-packages/eventlet/hubs/hub.py", line 476, in fire_timers
Aug 16 11:18:48 p091 granian[1182914]:     timer()
Aug 16 11:18:48 p091 granian[1182914]:   File "/usr/lib/python3.9/site-packages/eventlet/hubs/timer.py", line 59, in __call__
Aug 16 11:18:48 p091 granian[1182914]:     cb(*args, **kw)
Aug 16 11:18:48 p091 granian[1182914]:   File "/usr/lib/python3.9/site-packages/eventlet/semaphore.py", line 147, in _do_acquire
Aug 16 11:18:48 p091 granian[1182914]:     waiter.switch()
Aug 16 11:18:48 p091 granian[1182914]: greenlet.error: cannot switch to a different thread
... same traceback

Similar config works with uWSGI, important to have threads=1 not having same problem with eventlet. Unfortunately Nova is too heavy, i don't expect it'll be rewritten to use present async...

gi0baro commented 2 months ago

If you want to limit the Python concurrency in terms of threads, you should use --blocking-threads 1 in place of --threads (the latter regards Rust threads, not Python ones). Mind using this in WSGI will produce huge performance drops, as Granian will process 1 request at time per worker.

In general, there's nothing Granian can do to fix the issue you reported, as it's 100% dependant on the application implementation. Also, Granian in WSGI kinda replaces gevent/eventlet, as threads and concurrency is handled by Granian itself, so there are no plans to natively support this.

vooon commented 2 months ago

Nova (and Neutron) uses eventlet in many places, not only in API. I'll try --blocking-threads=1, but probably just leave built-in eventlet server.

Anyway, it's a great job!