J'utilise celerybeat pour lancer une tâche principale prenant en charge un certain nombre de tâches secondaires. J'ai déjà écrit les deux tâches.
Y a-t-il un moyen de le faire facilement? Celery permet-il d'exécuter des tâches à partir de tâches?
Mon exemple:
@task
def compute(users=None):
if users is None:
users = User.objects.all()
tasks = []
for user in users:
tasks.append(compute_for_user.subtask((user.id,)))
job = TaskSet(tasks)
job.apply_async() # raises a IOError: Socket closed
@task
def compute_for_user(user_id):
#do some stuff
compute
est appelé depuis célerybeat, mais provoque une erreur IOError lorsqu'il tente d'exécuter apply_async
. Des idées?
Pour répondre à vos questions d'ouverture: À compter de la version 2.0, Celery offre un moyen simple de démarrer des tâches à partir d'autres tâches. Ce que vous appelez des "tâches secondaires" sont ce qu’il appelle des "sous-tâches". Reportez-vous à la documentation de Ensembles de tâches, sous-tâches et rappels , auxquels @Paperino a eu la gentillesse de faire le lien.
Pour la version 3.0, Celery a changé en utilisant groups pour cela, et pour d’autres types de comportement.
Votre code indique que vous connaissez déjà cette interface. Votre question semble être la suivante: "Pourquoi est-ce que je reçois un 'socket fermé' IOError
lorsque j'essaie d'exécuter mon ensemble de sous-tâches?" Je pense que personne ne peut répondre à cette question, car vous n'avez pas fourni suffisamment d'informations sur votre programme. Votre extrait ne peut pas être lu tel quel, nous ne pouvons donc pas examiner le problème que vous avez vous-même. Veuillez poster le stacktrace fourni avec IOError
, et avec un peu de chance, quelqu'un qui pourra vous aider avec votre destructeur viendra.
Et depuis la version 3.0 'TaskSet' n'est plus le terme ... La nouveauté est Groupes, Chaînes et Accords, voir http://docs.celeryproject.org/en/3.1/whatsnew -3.0.html # group-chord-chain-are-now-subtasks
Vous pouvez utiliser quelque chose comme ceci (Support dans 3.0)
g = group(compute_for_user.s(user.id) for user in users)
g.apply_async()
Pour l'IOError mentionné, bien que les informations ici ne suffisent pas pour en déterminer la cause, je suppose que vous avez essayé d'établir une connexion à l'intérieur de la fonction task. Ainsi, chaque fois qu'une tâche est appelée, une nouvelle connexion est générée. Si la tâche doit être appelée mille fois, il y aura mille connexions. Cela va inonder le gestionnaire de socket système et IOError est sa plainte.