Джанго: сельдерей против каналов против просмотра

Предположим, что на моей странице есть кнопка, которая при нажатии запускает запрос ajax к моей конечной точке API, которая затем извлекает данные со стороннего сайта. Допустим, эта задача занимает около 2-5 секунд с тайм-аутом в 5 секунд. Каков идеальный способ сделать это:

  1. celery task.delay() в конечной точке API и вернуть URL-адрес для опроса результата каждые x интервалов.
  2. просто делай это на виду

Все учебники, которые я видел, предлагают способ сельдерея, но это похоже на много машин/накладных расходов для простого запроса с минимальной обработкой. Есть ли какой-то общепринятый порог (секунды до завершения и т. Д.), В котором можно было бы выбрать одно над другим?

Тогда есть django-каналы, которые, кажется, идеально подходят для этого. Но, на первый взгляд, грань между рабочими каналами и задачами celery кажется размытой. Могу ли я заменить сельдерей рабочими каналами и просто использовать его для указанной выше задачи? Будут ли каналы обрабатывать мои более длительные задачи? Каковы будут преимущества/недостатки каналов (либо с сельдереем, либо с заменой сельдерея)?

Наконец, какой из трех подходов (celery/channels/in-view) будет рекомендованным подходом к приведенному примерному сценарию?


person Verbal_Kint    schedule 05.06.2017    source источник


Ответы (1)


Я не эксперт по каналам, но поехали.

Каналы — это абстракция выше WSGI (новый протокол — ASGI), которая позволяет вам общаться по «абстрактным» каналам. Иногда вы будете использовать HTTP, иногда веб-сокеты, иногда другие вещи, которые вы можете использовать практически для любого шаблона связи.

Celery устроен аналогичным образом, он использует шину сообщений (иногда более сложный механизм брокера в зависимости от того, как вы его запускаете) для отправки работы на рабочую машину, которая может отправлять обратно необязательные результаты.

Теперь, что вы выбираете?

В представлении

Я бы избегал этого, если у вас нет представления, специально предназначенного для этой цели. Вам нужно будет убедиться, что ваш стек может обрабатывать долгоживущие соединения (например, маршрутизатор heroku будет жаловаться, если это займет более 30 секунд), или вы захотите реализовать какой-нибудь интерфейс с длительным опросом.

С сельдереем

Вам нужно будет выполнить всю настройку, чтобы получить доступ к Интернету.

Наличие задачи, результаты которой вам нужны, потребует серверной части результатов и передачи идентификатора задачи.

Вам нужно будет реализовать представление, которое может запрашивать сельдерей, чтобы выяснить, где находится задача с точки зрения завершения, успеха и т. д.

Eg.

# kick of the task somewhere

def create_task(request, *args, **kwargs):
    task_id = some_task.delay(param)
    return Response({'task_id': task_id})

urls.py

url(r'^/tasks/<task_id>/$', name='task-progress')

просмотры.py

def task_progress_view(request, task_id):
    # get fancier here, this is just an example
    return Response(some_task.AsyncResult(task_id).state)

Это действительно упрощенный пример, но он должен подойти в качестве отправной точки.

С каналами

Вам нужно будет настроить шину, собрать необходимые представления, по сути, так же, как сельдерей, только вам все еще нужно будет иметь фрагмент кода, который извлекает данные с некоторой повторной попыткой, логикой тайм-аута и т. д.

Что выбрать

Celery позаботится о рабочей части, вам придется позаботиться об обновлениях и информировании вашего клиента. Каналы были бы разумным способом справиться с этим назад и к четвертому, но вам это может не понадобиться.

Я бы подумал, что еще нужно сделать. Большинству приложений в какой-то момент требуется асинхронная работа, потому что это часто диктуется бизнес-логикой. Если вы планируете использовать веб-сокеты и тому подобное, но не хотите разбивать свое приложение django на службы, я бы просто укусил пулю и сделал и то, и другое.

Если вам не нужно более одного протокола связи, просто используйте сельдерей и делайте представления.

person theWanderer4865    schedule 05.06.2017
comment
Итак, предполагая, что у меня уже настроен celery rabbitmq и на самом деле у меня нет особой потребности в протоколе ws (без чата или другой функции, зависящей от реального времени), тогда вы предлагаете просто сохранить простой опрос? У меня есть конечная точка API для запроса, который запускает задачу сельдерея. Считаете ли вы, что это представление специально разработано для этой цели? Я предполагаю, что работники каналов не являются заменой сельдерея, ваше объяснение, похоже, подразумевает, что опрос все еще происходит, но внутри (вам все еще нужен фрагмент кода, который...)? - person Verbal_Kint; 06.06.2017
comment
@Verbal_Kint Если вы хотите использовать веб-сокеты, вам нужно что-то, ожидающее обновлений задания, или вам нужно будет использовать какую-то систему событий с обратными вызовами для отправки сообщений пользователю по этим каналам. Имеет ли это смысл? Также я обновил ответ, дайте мне знать, если он все еще не ясен. - person theWanderer4865; 06.06.2017