Ответ
В Celery @task и @shared_task — это декораторы, используемые для определения асинхронных задач. Основное различие между ними заключается в способе их привязки к экземпляру приложения Celery.
-
@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 -
@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является более универсальным и простым в использовании.
Ответ 18+ 🔞
О, слушай, смотри, тут про Celery, про эти ёбаные декораторы @task и @shared_task. Вроде одно и то же, а нихуя — разница есть, как между "пойти нахуй" и "пойти нахуй, но с чувством, с толком, с расстановкой".
Вот смотри, блядь, чтобы не обосраться с конфигурацией.
@task — это как привязанный раб к конкретной конторе.
Этот декоратор ты цепляешь прямо к своему экземпляру приложения Celery. Типа app.task. Задача становится его личной собственностью, его сучкой. Если у тебя вдруг несколько этих Celery-приложений бегает, или ты импортируешь модуль, а приложение ещё не инициализировано — тут тебе и пиздец, Колян. Всё посыпется, как карточный домик от чиха.
from celery import Celery
app = Celery('my_app', broker='redis://localhost:6379/0')
@app.task # Вот, привязал намертво к этой конкретной 'app'. Как собака на цепи.
def add_bound(x, y):
return x + y
Вот, видишь? add_bound теперь принадлежит этому app. Другой дяде такой задачи не даст, жадный уёбок.
А вот @shared_task — это свободная касса, блядь. Независимый художник.
Его импортируешь прямо из celery и вешаешь на любую функцию. Эта штука не привязана ни к какому конкретному приложению. Она как бродячий пёс — любой Celery-инстанс, который её увидит, может взять и выполнить. В Django это вообще святое, потому что задачи раскиданы по разным папкам-приложениям, а Celery один на весь проект.
from celery import shared_task # Импортировал и похуй
@shared_task # Навесил и забыл. Свободная, блядь, птица.
def add_shared(x, y):
return x + y
Вот она, красота. Функция add_shared теперь готова служить любому, кто её позовёт. Универсальный солдат, ёпта.
Так когда что использовать, чтобы не вышло как всегда?
@shared_task— в 99% случаев, блядь. Особенно в Django или когда пишешь что-то типо библиотеки. Не паришься, импортируешь и всё. Гибко, просто, охуенно.@task— только если ты реально ебанутый и тебе нужно несколько разных Celery-приложений в одном проекте. И чтобы задачи из одного в другое не перетекали, как говно в проруби. Типа у тебя один воркер для срочных задач, другой для долгих, и конфиги у них разные. Вот тогда да, привязывай конкретную задачу к конкретномуapp. Но это такой высший пилотаж, на грани ебли с ослом.
Короче, если сомневаешься — @shared_task и в пизду. Не прогадаешь. А то начнёшь ебаться с привязками, а в итоге задачи просто не будут запускаться, и будешь сидеть, чесать репу: "Ну что за хуйня?".