Django: Как игнорировать задачи с помощью Celery?

Не изменяя сам код, есть ли способ игнорировать задачи в Celery?

Например, при использовании почты Django существует фиктивный сервер настройка. Это идеально, поскольку позволяет мне из файла .env деактивировать отправку почты в некоторых средах (например, при тестировании или подготовке). Сам код, который обрабатывает отправку почты, не изменяется операторами if или декораторами.

Я знаю, что для задач сельдерея я мог бы сделать это в коде, используя макеты или декораторы, но я хотел бы сделать это чистым способом, совместимым с 12 факторами, например, с почтой Django. Есть идеи?

РЕДАКТИРОВАТЬ, чтобы объяснить, почему я хочу это сделать:

Одна из основных причин этого заключается в том, что он создает связь между веб-сервером Django и задачами Celery. Например, при запуске юнит-тестов, если сервер-брокер (у меня Redis) не запущен, то при вызове метода delay() он зависает навсегда, потому что нет тайм-аута, когда Celery пытается отправить задачу в Redis. С точки зрения архитектуры это очень плохо. Я бы хотел, чтобы мои модульные тесты могли работать правильно без необходимости запуска брокера Celery!

Спасибо!


person David D.    schedule 22.02.2020    source источник
comment
Если вы не запустите работника сельдерея, будет ли выполняться задача?   -  person JPG    schedule 22.02.2020
comment
@ArakkalAbu Пожалуйста, проверьте мое редактирование, чтобы понять цель :)   -  person David D.    schedule 22.02.2020


Ответы (1)


Что касается связи, ваше приложение Django все равно будет привязано к celery, если вы используете фиктивный бэкэнд. Просто ваши задачи не будут выполняться. Может быть, это приемлемо в вашем случае, но, на мой взгляд, это может вызвать некоторые проблемы. Например, если фрагмент кода, который вы пытаетесь протестировать, отправляет задачу в celery, а в более поздней части пытается получить результат для этой задачи, произойдет сбой. Потому что фиктивный бэкенд никогда не выполнит задачу.

Для модульного тестирования, как вы упомянули в своем вопросе, вы можете использовать task_always_eager. Если вы включите его, ваше приложение Django больше не будет зависеть от работающего воркера. Он будет выполнять задачи в одном потоке синхронно и возвращать результат.

person Nafees Anwar    schedule 22.02.2020
comment
task_always_eager — отличный способ защитить юнит-тесты от зависания, спасибо за идею! А что касается производственного кода, как вы гарантируете, что Redis не зависнет? (в моем случае фоновые задачи не критичны для бизнеса, но веб-сервер критичен). Думаю, мне следует добавить журналы тайм-аута и ошибок, когда Celery пытается подключиться к Redis. - person David D.; 22.02.2020
comment
@ДэвидД. Celery не зависает, если Redis (или любой другой используемый вами брокер) не работает. Сразу выдает ошибку. Однако, если воркер не работает, задача сохраняется в брокере и выполняется, когда воркер работает. - person Nafees Anwar; 22.02.2020
comment
Ооо... Я думал, что это поведение по умолчанию, но после некоторых исследований оказалось, что это хорошо известная ошибка: github.com/celery/celery/issues/4296 - person David D.; 23.02.2020
comment
@ДэвидД. Попробуйте обновить версию сельдерея. Я не сталкиваюсь с такими проблемами при использовании celery 4.4.0. - person Nafees Anwar; 23.02.2020
comment
Я не думаю, что это отвечает на заданный вопрос. Конечно, я мог бы включить task_always_eager, но скажем, у меня есть функция, которая не зависит от результата задачи, которую она вызывает. Я не хочу тратить время на запуск этой задачи во время моих тестов, я просто хочу, чтобы вызов apply_async() или delay() молча игнорировался. В идеале, не издеваясь над каждым местом в моей программе, может быть вызвана задача (что может быть через сигнал и т. Д.). - person Dustin Martin; 12.06.2021
comment
Кстати, метод, который, кажется, работает для Redis, заключается в изменении broker_url при выполнении тестов, чтобы задачи помещались в неиспользуемый индекс БД, который рабочие Celery не прослушивают. Затем этот индекс БД может очищаться после каждого тестового запуска. - person Dustin Martin; 12.06.2021
comment
@DustinMartin ОП просил создать разделение между брокером и модульными тестами. Как размещение задач в неиспользуемом индексе БД создает развязку? PS: у вас все еще может быть этот неиспользуемый индекс БД без изменения файла broker_url. Прочитайте второй комментарий. - person Nafees Anwar; 12.06.2021