Here is a minimal blueprint to reproduce the issue:
@my_blueprint.route('/my_route', methods=['POST'])
async def my_route() -> Response:
await asyncio.sleep(5)
return format_json_response(
{
'success': True,
},
)
It works perfectly fine when making calls one by one with some delay between the calls. But if making concurrent calls or just making serial calls too fast, it produces the following error:
Traceback (most recent call last):
File "[myvenv]lib/python3.8/site-packages/gunicorn/workers/base_async.py", line 55, in handle
self.handle_request(listener_name, req, client, addr)
File "[myvenv]lib/python3.8/site-packages/gunicorn/workers/ggevent.py", line 127, in handle_request
super().handle_request(listener_name, req, sock, addr)
File "[myvenv]lib/python3.8/site-packages/gunicorn/workers/base_async.py", line 108, in handle_request
respiter = self.wsgi(environ, resp.start_response)
File "[myvenv]lib/python3.8/site-packages/flask/app.py", line 2213, in __call__
return self.wsgi_app(environ, start_response)
File "[myvenv]lib/python3.8/site-packages/flask/app.py", line 2193, in wsgi_app
response = self.handle_exception(e)
File "[myvenv]lib/python3.8/site-packages/flask_cors/extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "[myvenv]lib/python3.8/site-packages/flask/app.py", line 2190, in wsgi_app
response = self.full_dispatch_request()
File "[myvenv]lib/python3.8/site-packages/flask/app.py", line 1486, in full_dispatch_request
rv = self.handle_user_exception(e)
File "[myvenv]lib/python3.8/site-packages/flask_cors/extension.py", line 165, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "[myvenv]lib/python3.8/site-packages/flask/app.py", line 1484, in full_dispatch_request
rv = self.dispatch_request()
File "[myvenv]lib/python3.8/site-packages/flask_protobuf/api.py", line 91, in dispatch_request
rv = original_dispatch_request(self)
File "[myvenv]lib/python3.8/site-packages/flask/app.py", line 1469, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "[myvenv]lib/python3.8/site-packages/asgiref/sync.py", line 209, in __call__
raise RuntimeError(
RuntimeError: You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly.
Here is some additional environment information:
gevent==23.7.0
flask[async]==2.3.3
gunicorn[gevent]==20.1.0
gunicorn wsgi:app --workers=2 -k gevent
The actual endpoint does some complex async/await parallel processing, but it behaves exactly like this minimal example.
I'm expecting the endpoint to work without any error messages.
I think this issue from
async def my_route. It will use AsyncToSync class so it cannot proccess into the main thread which the gevent running.So, Change the mode gunicorn to
gthreadto fix it.gunicorn wsgi:app --workers=2 -k gthread