web-dev-qa-db-fra.com

Ajoutez n tâches à la file d'attente de céleri et attendez les résultats

J'ajouterais plusieurs tâches à la file d'attente de céleri et j'attendrais les résultats. J'ai différentes idées sur la façon dont j'y arriverais en utilisant une forme de stockage partagé (memcached, redis, db, etc.), cependant, j'aurais pensé que c'est quelque chose que Celery peut gérer automatiquement, mais je ne trouve aucune ressource en ligne.

exemple de code

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

    return c.all_results_some_how()
23
Prydie

Pour Céleri> = 3.0 , TaskSet est obsolète en faveur de groupe .

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),
])

Démarrez le groupe en arrière-plan:

result = job.apply_async()

Attendre:

result.join()
37
laffuste

Task.delay renvoie AsyncResult . Utilisation AsyncResult.get pour obtenir le résultat de chaque tâche.

Pour ce faire, vous devez conserver des références aux tâches.

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

Ou vous pouvez utiliser ResultSet :

[~ # ~] mise à jour [~ # ~] : ResultSet est déconseillé, veuillez consulter @ laffuste's answer .

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

J'ai le pressentiment que vous ne voulez pas vraiment le délai, mais la fonction asynchrone de Celery.

Je pense que vous voulez vraiment un 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()
2