41

私はセロリを使用しています。順番に実行する必要があるいくつかのタスクがあります。

たとえば、次のタスクがあります。

@celery.task
def tprint(word):
    print word

そして、私はこのようなことをしたい:

>>> chain(tprint.s('a') | tprint.s('b'))()

それから私は得るTypeError: tprint() takes exactly 1 argument (2 given)

コードと同じです。この状況では、タスクのグループの後にタスクを実行する必要があります。

>>> chord([tprint.s('a'), tprint.s('b')])(tprint.s('c'))

では、この状況にどう対処するか?各タスクの結果は気にしませんが、順番に実行する必要があります。


2 番目のパラメーターを追加しても機能しません。

@celery.task
def tprint(word, ignore=None):
    print word

>>> chain(tprint.s('a', 0) | tprint.s('b'))()

これにより、「a」と「None」が出力されます。

4

4 に答える 4

91

連鎖などの結果を無視する組み込み機能があります - 不変サブタスク。.s() または .subtask(immutable=True) の代わりに .si() ショートカットを使用できます

詳細はこちら: http://docs.celeryproject.org/en/master/userguide/canvas.html#immutability

于 2012-12-09T14:51:37.047 に答える
3

考えられる解決策の 1 つが既に投稿されていますが、さらなる説明と代替の解決策 (場合によってはより優れた解決策) を追加したいと思います。

表示されているエラーは、タスクのシグネチャで 2 番目のパラメーターを考慮する必要があることを示しています。これは、 でタスクを呼び出すときにchain、Celery が各タスクresultを次のタスクの最初のパラメーターとして自動的にプッシュするためです。

ドキュメントから:

タスクは一緒にリンクできます。実際には、コールバック タスクを追加することを意味します。

>>> res = add.apply_async((2, 2), link=mul.s(16))
>>> res.get()
4

リンクされたタスクは、親タスクの結果を最初の引数として適用されます

したがって、あなたの場合、次のようにタスクを書き直すことができます。

@celery.task
def tprint(result, word):
    print word

結果に対して何もしない場合は、次のようにデコレータを変更して無視することもできます。

@celery.task(ignore_result=True)

そして、タスク署名を変更する必要はありません。

申し訳ありませんが、最後の点についてはさらに調査する必要があります。

于 2016-10-10T08:33:51.590 に答える
-1

このようなことを試すことができます。関数 tprint の単一のパラメーターを持つ代わりに、2 つのパラメーターを持つことができます

def tprint(word, x=None):
    print word

それから

chain(tprint.s('a', 0) | tprint.s('b'))()
于 2012-12-03T05:08:30.930 に答える
-2

最後に、これに対する回避策を見つけてください。チェーン デコレータがこの作業を行います。

セロリがどのようにそれを行ったのか正確にはわかりませんが、セロリは前のタスクの結果を次のタスクの最初の引数に強制的にバインドしているようです。

次に例を示します。

def chain_deco(func):

    @functools.wraps(func)
    def wrapper(chain=None, *args, **kwargs):
        if chain is False:
            return False

        func(*args, **kwargs)
        return True

    return wrapper


@celery.task
@chain_deco
def hello(word):
    print "hello %s" % word

これで正しい出力が得られます。

>>> (hello.s(word='a') | hello.s(word='b'))()

また

>>> (hello.s('a') | hello.s('b'))(True)

また、デコレーターはチェーンを途中で停止する機能も提供します (後のカスケードを失敗させます)。

同じメカニズムが機能するはずchordです。

于 2012-12-04T09:56:35.223 に答える