5

手動のトランザクション管理で Django - Celery タスクを実行したいのですが、アノテーションがスタックしないようです。

例えば

def ping():
    print 'ping'
    pong.delay('arg')

@task(ignore_result=True)
@transaction.commit_manually()
def pong(arg):
    print 'pong: %s' % arg
    transaction.rollback()

結果は

TypeError: pong() got an unexpected keyword argument 'task_name'

一方、アノテーションの順序を逆にすると、

---> 22     pong.delay('arg')

AttributeError: 'function' object has no attribute 'delay'

それは理にかなっていますが、良い回避策を見つけるのに苦労しています。Django のドキュメントには、注釈の代替手段については言及されていません。必要がない場合は、各セロリ タスクのクラスを作成したくありません。

何か案は?

4

2 に答える 2

8

以前は、Celery には、タスクが受け入れた場合にデフォルトのキーワード引数のセットがタスクに渡される魔法がありました。

バージョン 2.2 以降、この動作を無効にすることができますが、最も簡単な方法は、 の代わりにtaskからデコレータをインポートすることです。celery.taskcelery.decorators

from celery.task import task

@task
@transaction.commit_manually
def t():
    pass

decoratorsモジュールは非推奨であり、3.0 で完全に削除されます。「マジック キーワード引数」についても同様です。

注: カスタム Task クラスの場合、accept_magic_kwargs属性を False に設定する必要があります。

class MyTask(Task):
    accept_magic_kwargs = False

注 2: カスタム デコレータが を使用して関数の名前を保持していることを確認してください。functools.wrapsそうしないと、タスクが間違った名前で終了します。

于 2011-09-09T16:23:20.133 に答える
6

タスクデコレータは、メソッドをターゲットとしてclass x(Task)関数からを生成します。runクラスを定義し、メソッドを装飾することをお勧めします。

未テスト例:

class pong(Task):
  ignore_result = True

  @transaction.commit_manually()
  def run(self,arg,**kwargs):
    print 'pong: %s' % arg
    transaction.rollback()
于 2011-09-08T15:30:37.933 に答える