I am running 2 kinds of django web server simultaneously in my architecture, gunicorn(WSGI with worker_class=gevent) and channels(ASGI) respectively. WSGI server is responsible for handling HTTP request and channels is responsible for websocket connections.
There is an API on WSGI server that would run a SQL query, and then trigger sending message to a particular user via websocket. I called async_to_sync to wrap the channel_layer.group_send, but sometimes error occurrs.
Here's the code
def some_view(request):
# database operations
# ...
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
group_name,
{
'type': 'send_function',
'data': data
},
)
Most of the time it works fine, however, sometimes RuntimeError "You cannot use AsyncToSync in the same thread as an async event loop - just await the async function directly." occurred. This happened because there is a running event loop in current thread. I think it's probably that django is reusing threads and each request would initialize an event loop due to async_to_sync.
My first solution is to create event_loop for each request and then call loop.run_until_complete, but it cause another RuntimeError "Cannot run the event loop while another loop is running"
Then I tried to check if there is running event loop before call create event loop, if an event loop is running, get the running loop first, then call running_event_loop.run_until_complete. But it seems stupid and still have a slight chance to cause the same RuntimeError.
Is there any way to solve this problem?
Note that I set DJANGO_ALLOW_ASYNC_UNSAFE to 'true'