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

Я хочу запускать это задание каждые три минуты, и вот что у меня есть

tasks.py

@shared_task
def save_hackathon_to_db():
    logger.info('ran')
    loop = asyncio.get_event_loop()
    statuses = ['ended', 'open', 'upcoming']
    loop.run_until_complete(send_data(statuses))
    logger.info('ended')

settings.py

CELERY_BEAT_SCHEDULE = {
    "devpost_api_task": {
        "task": "backend.tasks.save_hackathon_to_db",
        "schedule": crontab(minute="*/3"),
    },
}

Однако он не запускается каждые 3 минуты, он запускается только тогда, когда я посылаю запрос post на адрес http://0.0.0.0:8000/hackathon/task, а затем запрос get на адрес http://0.0.0.0:8000/hackathon/<task_id>

Это код для функций, относящихся к маршрутам соответственно

@csrf_exempt
def run_task(request):
    if request.method == 'POST':
        task = save_hackathon_to_db.delay()
        return JsonResponse({"task_id": task.id}, status=202)


@csrf_exempt
def get_status(request, task_id):
    print(task_id)
    task_result = AsyncResult(task_id)
    result = {
        "task_id": task_id,
        "task_status": task_result.status,
        "task_result": task_result.result
    }
    return JsonResponse(result, status=200)

Мы знаем, что:

  • Ваше приложение Django запущено, потому что оно может принимать запросы GET / POST
    • например, python manage.py runserver
  • Ваш Celery worker (consumer) запущен, потому что он может принимать асинхронные .delay() запросы от приложения Django
    • например, celery --app=my_proj worker --loglevel=INFO

Возможное решение 1

Проверьте, запущен ли также планировщик Celery (producer).

  • например, celery --app=my_proj beat --loglevel=INFO

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

Дополнительная информация о запуске планировщика здесь.

Возможное решение 2

Проверьте наличие журналов ошибок в экземпляре рабочего (потребитель). Возможно, планировщик (производитель) работает и выставляет задачи в очередь, но рабочий не может их обработать, возможно, из-за того, что реализация задачи не найдена. В этом случае обязательно укажите местоположение задачи в конфигурации приложения celery, например, celery_app.conf.update(imports=['backend.tasks']).


Чтобы проверить, правильно ли работает планировщик, в журналах должно быть видно, что он правильно выставляет задание в очередь каждые 3 минуты:

$ celery --app=my_proj beat --loglevel=INFO
celery beat v5.1.2 (sun-harmonics) is starting.
__    -    ... __   -        _
LocalTime -> 2021-09-11 01:38:05
Configuration ->
    . broker -> amqp://guest:**@127.0.0.1:5672//
    . loader -> celery.loaders.app.AppLoader
    . scheduler -> celery.beat.PersistentScheduler
    . db -> celerybeat-schedule
    . logfile -> [stderr]@%INFO
    . maxinterval -> 5.00 minutes (300s)
[2021-09-11 01:38:05,523: INFO/MainProcess] beat: Starting...
[2021-09-11 01:38:05,544: INFO/MainProcess] Scheduler: Sending due task backend.tasks.save_hackathon_to_db (devpost_api_task)
[2021-09-11 01:41:05,613: INFO/MainProcess] Scheduler: Sending due task backend.tasks.save_hackathon_to_db (devpost_api_task)
[2021-09-11 01:44:05,638: INFO/MainProcess] Scheduler: Sending due task backend.tasks.save_hackathon_to_db (devpost_api_task)
...
Вернуться на верх