web-dev-qa-db-ja.com

クラスベースのタスクに@shared_taskデコレータを使用する方法

ドキュメント the @shared_taskデコレータを使用すると、具体的なアプリインスタンスなしでタスクを作成できます。与えられた例は、関数ベースのタスクを装飾する方法を示しています。

クラスベースのタスクを装飾する方法は?

30
Juan Riaza

@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=再利用可能なアプリがプロジェクトモジュールに依存することは意味がありません。

18
Saurabh

リンク先のドキュメントには次のように書かれています。

@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_taskswillで修飾された各関数がapp引数で呼び出されることを確認できます。

9
jdhildeb