Comments 12
Раз упомянули uWSGI, то для решения первых двух задач, можете использовать его spooler, уменьшите внешние зависимости проекта.
Для обработки таких запросов подходит асинхронный фреймворк Tornado.
Что мешает сделать абсолютно такую же вьюху в Django?
Django будет обрабатывать эти запросы синхронно. А их может быть сильно больше чем к основному приложению. Tornado или другой асинхронный фреймворк лучше справляются с этой задачей.
Django будет обрабатывать эти запросы синхронно.
В вашем коде Tornado тоже нет ни единой строчки асинхронного кода — разницы не будет никакой.
А их может быть сильно больше чем к основному приложению.
И они всё равно будут обрабатываться быстро, потому что отправка задачи в Celery это единственное, чем будет заниматься этот код, так что это совершенно не проблема. (Ну, если речь идёт не о тысячах запросов в секунду, но на тысячах запросов в секунду вылезет куча других проблем)
Раз уж упомянули про вебсокеты, то привели бы для примера вариант реализации. Это было бы одно из интереснейших мест статьи.
Параллельно выполняется Celery-таск, который по завершению возвращает ответ по вебсокету
Особенно интересен вот этот момент. Каким образом таск, выполненный celery-воркером, отправляет что-то в конкретное вебсокетное соединение.
Или клиент, получив от endpoint'а uuid celery-задания, сам по сокету периодически опрашивает сервер на тему результата выполнения этого задания, и сервер возвращает текущий статус задания и результат его выполнения (если он есть)?
Это можно реализовать, например, с помощью Tornado или asyncio + Redis pub/sub + sockjs (https://github.com/leporo/tornado-redis#pubsub).
На фронте генерируем случайный uuid, подписываемся и отправляем в запросе на бэкенд. В Celery результат таска пишем в Redis канал с тем uuid в имени. Результат отправляется подписанному клиенту.
На фронте генерируем случайный uuid, подписываемся и отправляем в запросе на бэкенд. В Celery результат таска пишем в Redis канал с тем uuid в имени. Результат отправляется подписанному клиенту.
А зачем на фронте генерировать UUID? Клиент хоть что сможет передать на сервер. Это же дыра в безопасности.
Чтобы на конкретный запрос вернуть данные, запрос от клиента, там и request_uuid генерится. У одного юзера во время одной сессии может быть сгенерировано много таких запросов с разным request_uuid.
Еще user_id используется в имени канала.
Еще user_id используется в имени канала.
А зачем вообще генерировать UUID на фронте? Каждой задаче Celery назначается UUID, вот его и нужно отдавать клиенту, чтобы он дергал вьюшку с этим UUID, а в ней проверяется завершилась ли эта задача. Зачем все переусложнять с pubsub?
Sign up to leave a comment.
3 кейса для использования Celery в Django-приложении