В чем различия между декораторами `@task` и `@shared_task` в Celery?

Ответ

В Celery @task и @shared_task — это декораторы, используемые для определения асинхронных задач. Основное различие между ними заключается в способе их привязки к экземпляру приложения Celery.

  1. @task (Привязка к экземпляру приложения Celery)

    • Назначение: Используется для определения задач, которые явно привязаны к конкретному экземпляру приложения Celery.
    • Использование: Декоратор @task вызывается через объект приложения Celery (например, app.task). Это означает, что задача становится частью этого конкретного приложения.
    • Контекст: Если у вас несколько приложений Celery или вы работаете в среде, где приложение Celery может быть не инициализировано при импорте модуля (например, в некоторых тестах или скриптах), использование @task может потребовать дополнительной настройки или привести к ошибкам.

    Пример app.task:

    from celery import Celery
    
    app = Celery('my_app', broker='redis://localhost:6379/0')
    
    @app.task
    def add_bound(x, y):
        return x + y
  2. @shared_task (Независимая от приложения задача)

    • Назначение: Используется для определения задач, которые не привязаны к конкретному экземпляру приложения Celery. Они могут быть импортированы и использованы любым приложением Celery, которое их обнаружит.
    • Использование: Декоратор @shared_task импортируется напрямую из модуля celery (например, from celery import shared_task).
    • Контекст: Это предпочтительный способ определения задач в большинстве проектов, особенно в Django, где задачи могут быть определены в разных приложениях и должны быть доступны глобально без явной привязки к одному экземпляру Celery app.

    Пример shared_task:

    from celery import shared_task
    
    @shared_task
    def add_shared(x, y):
        return x + y

Когда использовать:

  • @shared_task: Рекомендуется для большинства случаев, особенно в проектах на Django или при создании библиотек. Это обеспечивает гибкость и позволяет легко импортировать задачи из любого места без необходимости передавать экземпляр app.
  • @task: Используется, когда вам нужна специфическая привязка задачи к определенному экземпляру приложения Celery, например, если у вас есть несколько Celery приложений с разными конфигурациями, и задача должна принадлежать только одному из них. Однако, в большинстве случаев, @shared_task является более универсальным и простым в использовании.