ドキュメント the @shared_task
デコレータを使用すると、具体的なアプリインスタンスなしでタスクを作成できます。与えられた例は、関数ベースのタスクを装飾する方法を示しています。
クラスベースのタスクを装飾する方法は?
@taskと@shared_taskの違いを説明したcelery-usersスレッドからのAskの引用。 ここにスレッドへのリンクがあります
TL; DR; @shared_taskは、アプリごとにタスクの独立したインスタンスを作成し、タスクを再利用可能にします。
@task(shared = True)と@shared_taskには違いがあります
タスクデコレータは、デフォルトでアプリ間でタスクを共有します。
app1 = Celery()
@app1.task
def test():
pass
app2 = Celery()
テストタスクは両方のアプリに登録されます。
assert app1.tasks[test.name]
assert app2.tasks[test.name]
ただし、「test」という名前は常に「app1」アプリにバインドされたインスタンスを指すため、app1の構成を使用して構成されます。
assert test.app is app1
@shared_taskデコレータは、current_appのタスクインスタンスを常に使用するプロキシを返します。
app1 = Celery()
@shared_task
def test():
pass
assert test.app is app1
app2 = Celery()
assert test.app is app2
@shared_taskデコレータは、ユーザーのアプリにアクセスできないため、ライブラリおよび再利用可能なアプリに役立ちます。
さらに、デフォルトのDjango=サンプルプロジェクトは、Djangoプロジェクトの一部としてアプリインスタンスを定義します。
proj.celeryインポートアプリから
そして、Django=再利用可能なアプリがプロジェクトモジュールに依存することは意味がありません。
リンク先のドキュメントには次のように書かれています。
@shared_taskデコレータを使用すると、具体的なアプリインスタンスがなくてもタスクを作成できます。
私が知る限り、ドキュメントは誤解を招くものであり、次のように言う必要があります。
@shared_taskデコレータを使用すると、任意のアプリで使用できるタスクを作成できます。
実際、タスクはアプリインスタンスにアタッチする必要があります。私の証拠はセロリのソースファイルcelery/app/builtins.py
から来ています:
def shared_task(constructor):
"""Decorator that specifies a function that generates a built-in task.
The function will then be called for every new app instance created
(lazily, so more exactly when the task registry for that app is needed).
The function must take a single ``app`` argument.
"""
_shared_tasks.add(constructor)
return constructor
looksこのデコレータを使用して、具体的なアプリインスタンスを持たずにタスクを作成できるようになりますが、実際には、デコレーションされた関数はアプリの引数をとる必要があります(ソースコメントを参照)。
次の機能は次のとおりです。
def load_shared_tasks(app):
"""Create built-in tasks for an app instance."""
constructors = set(_shared_tasks)
for constructor in constructors:
constructor(app)
ここで、@shared_tasks
willで修飾された各関数がapp
引数で呼び出されることを確認できます。