web-dev-qa-db-ja.com

セロリキューにn個のタスクを追加し、結果を待ちます

セロリキューに複数のタスクを追加して、結果を待ちます。何らかの形の共有ストレージ(memcached、redis、dbなど)を使用してこれを実現する方法はさまざまですが、Celeryが自動的に処理できるものだと思っていましたが、オンラインでリソースを見つけることができませんでした。

コード例

def do_tasks(b):
    for a in b:
        c.delay(a)

    return c.all_results_some_how()
23
Prydie

Celery> = 3.0の場合、TaskSetは deprecated -- group を優先します。

from celery import group
from tasks import add

job = group([
             add.s(2, 2),
             add.s(4, 4),
             add.s(8, 8),
             add.s(16, 16),
             add.s(32, 32),
])

バックグラウンドでグループを開始します。

result = job.apply_async()

待つ:

result.join()
37
laffuste

Task.delayAsyncResult を返します。使用する - AsyncResult.get 各タスクの結果を取得します。

そのためには、タスクへの参照を維持する必要があります。

def do_tasks(b):
    tasks = []
    for a in b:
        tasks.append(c.delay(a))
    return [t.get() for t in tasks]

または ResultSet を使用できます:

[〜#〜] update [〜#〜]ResultSetは非推奨です。参照してください @ laffusteの回答

def do_tasks(b):
    rs = ResultSet([])
    for a in b:
        rs.add(c.delay(a))
    return rs.get()
14
falsetru

私はあなたが本当に遅延を望んでいないのではなく、Celeryの非同期機能を持っている予感を持っています。

あなたは本当に TaskSet が欲しいと思います:

from celery.task.sets import TaskSet
from someapp.tasks import sometask

def do_tasks(b):
    job = TaskSet([sometask.subtask((a,)) for a in b])
    result = job.apply_async()
    # might want to handle result.successful() == False
    return result.join()