Вызов функции синхронизации вне потребителя (Django Channels)
Существует 2 вида веб-сервера django, gunicorn(WSGI) и channels(ASGI) соответственно. Сервер WSGI отвечает за обработку HTTP запросов, а channels отвечает за соединения websocket.
На сервере WSGI есть API, который выполняет SQL-запрос, а затем вызывает отправку сообщения определенному пользователю через websocket. Я вызвал async_to_sync, чтобы обернуть channel_layer.group_send, но иногда возникает ошибка.
Вот код
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
},
)
В большинстве случаев все работает нормально, однако иногда возникает RuntimeError "Вы не можете использовать AsyncToSync в том же потоке, что и цикл событий async - просто ожидайте функцию async напрямую.". Это произошло потому, что в текущем потоке запущен цикл событий. Я думаю, что это возможно из-за того, что django повторно использует потоки и каждый запрос инициализирует цикл событий.
Мое первое решение - создать event_loop для каждого запроса и затем вызвать loop.run_until_complete, но это вызывает другую ошибку RuntimeError "Cannot run the event loop while another loop is running"
Тогда я попытался проверить, запущен ли цикл событий перед вызовом create event loop, если цикл событий запущен, сначала получить запущенный цикл, затем вызвать running_event_loop.run_until_complete. Но это кажется глупым и все еще имеет небольшой шанс вызвать ту же самую RuntimeError.
Есть ли способ решить эту проблему?
Обратите внимание, что я установил DJANGO_ALLOW_ASYNC_UNSAFE в 'true'