Как автоматически настраивать периодические задания

У меня есть задача celery в одном из моих приложений django.

Мои сервисы django, celery и django-celery-beat запускаются в собственных контейнерах docker. Поскольку это унаследованный проект, я предполагаю, что они и так прекрасно взаимодействуют с текущим конфигом.

Я хочу, чтобы при развертывании/запуске приложения оно автоматически находило мои perioidc-задачи и регистрировало их в таблицах базы данных django celery beat.

Моя задача:

# project.an_app.tasks.generate_statements
from config import celery_app

@celery_app.task(...)
def generate_statements():
    print("Statment generation runs. Current date and time:", datetime.now())
    # my task logic

Это одно из решений, которое я нашел. Но оно срабатывает только тогда, когда я пытаюсь получить доступ к таблицам Periodic tasks через админку сайта (возможно, срабатывали бы и другие способы, которые взаимодействуют с этими таблицами, но я не хочу "ждать" ничего подобного).

def schedule_task():
    interval, _ = IntervalSchedule.objects.get_or_create(
        every=30,
        period=IntervalSchedule.SECONDS,
    )

    PeriodicTask.objects.get_or_create(
        interval=interval,
        name="generate-statements",
        task=project.an_app.tasks.generate_statements,
    )
    
schedule_task()

Просматривая наш унаследованный код, я обнаружил следующее: вот это выглядит

from project.an_app.tasks import generate_statements

@celery_app.on_after_finalize.connect
def register_periodic_tasks(sender, **kwargs):
    """
    Callback for Celery to register periodic tasks.
    """
    sender.add_periodic_task(
        30.0,
        task=generate_statements,
        name="generate-statements",
    )

Задача скопированного кода действительно уже django_celery_beat_periodictask таблица. Так что я бы сказал, что это работает. Однако эта версия не создала мою задачу, когда я пересобирал докер-контейнеры.

Также я продолжаю находить решения простого добавления в файл settings.py:

CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"

CELERY_BEAT_SCHEDULE = {
    "task-name": {
        "task": "project.an_app.tasks.generate_statements",
        "schedule": timedelta(seconds=30),
    },
}

Этот не сработал так же хорошо.

Может ли кто-нибудь прояснить, какое решение является наиболее подходящим для того, что мне нужно, и чего мне не хватает в каждом случае?

Если посмотреть на приложение Django, которое у меня есть, то первый код находится в файле project/_init.py

from .celery import app as celery_app

__all__ = ("celery_app",)

Тогда у меня есть celery.py:

import os

from celery import Celery


os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")

app = Celery("core")
app.config_from_object("django.conf:settings", namespace="CELERY")
app.autodiscover_tasks()

Это должно гарантировать, что celery будет загружен при запуске проекта и что задачи будут автообнаружены.

Не знаю, поможет ли это в вашем случае. Но, возможно, стоит проверить.

Вернуться на верх