web-dev-qa-db-fra.com

Comment vérifier le statut des tâches dans le céleri?

Comment vérifier si une tâche est en cours d'exécution dans le céleri (en particulier, j'utilise céleri-Django)?

J'ai lu la documentation et j'ai cherché sur Google, mais je ne vois pas d'appel comme:

my_example_task.state() == RUNNING

Mon cas d'utilisation est que je dispose d'un service externe (Java) pour le transcodage. Lorsque j'envoie un document à transcoder, je souhaite vérifier si la tâche qui exécute ce service est en cours d'exécution et, dans le cas contraire, le (re) le démarrer.

J'utilise les versions stables actuelles - 2.4, je crois.

78
Marcin

Chaque objet Task a une propriété .request, qui le contient AsyncRequest. En conséquence, la ligne suivante donne l'état d'une tâche task:

task.AsyncResult(task.request.id).state
53
Marcin

Renvoie le task_id (qui provient de .delay ()) et interroge l'instance du céleri après sur l'état:

x = method.delay(1,2)
print x.task_id

Lorsque vous le demandez, obtenez un nouveau AsyncResult en utilisant cet ID_tâche:

from celery.result import AsyncResult
res = AsyncResult("your-task-id")
res.ready()
77
Gregor

La création d'un objet AsyncResult à partir de l'identifiant de tâche est recommandée dans le FAQ pour obtenir le statut de la tâche lorsque vous ne disposez que de l'identifiant de la tâche.

Cependant, à partir de Celery 3.x, il existe des réserves importantes qui pourraient piquer les gens s’ils ne leur prêtent pas attention. Cela dépend vraiment du scénario d'utilisation.

Par défaut, Celery n'enregistre pas l'état "en cours d'exécution".

Pour que Celery puisse enregistrer qu'une tâche est en cours d'exécution, vous devez définir task_track_started sur True. Voici une tâche simple qui teste ceci:

@app.task(bind=True)
def test(self):
    print self.AsyncResult(self.request.id).state

Lorsque task_track_started est False, la valeur par défaut, l'état d'affichage est PENDING même si la tâche a démarré. Si vous définissez task_track_started sur True, l'état sera STARTED.

L'état PENDING signifie "je ne sais pas".

Une AsyncResult avec l'état PENDING ne veut rien dire de plus que Celery ne connaît pas le statut de la tâche. Cela pourrait être dû à un certain nombre de raisons.

D'une part, AsyncResult peut être construit avec des identifiants de tâches non valides. Ces tâches seront considérées comme en suspens par le céleri:

>>> task.AsyncResult("invalid").status
'PENDING'

Ok, donc personne ne va alimenter évidemment identifiants invalides à AsyncResult. Assez bien, mais cela a également pour effet que AsyncResult considérera également une tâche exécutée avec succès mais que Celery a oublié comme étant PENDING. Encore une fois, dans certains scénarios de cas d'utilisation un problème. Une partie du problème repose sur la façon dont Celery est configuré pour conserver les résultats des tâches, car cela dépend de la disponibilité des "pierres tombales" dans le backend des résultats. ("Tombstones" est le terme utilisé dans la documentation de Celery pour désigner les fragments de données qui enregistrent le déroulement de la tâche.) Utiliser AsyncResult ne fonctionnera pas du tout si task_ignore_result est True. Un problème plus épineux est que Celery expire les pierres tombales par défaut. Le paramètre result_expires par défaut est défini sur 24 heures. Ainsi, si vous lancez une tâche et enregistrez l'ID dans la mémoire de stockage à long terme, et plus de 24 heures plus tard, vous créez une AsyncResult avec elle, le statut sera PENDING

Toutes les "tâches réelles" commencent dans l'état PENDING. Donc, obtenir PENDING sur une tâche peut signifier que la tâche a été demandée mais n'a jamais progressé plus loin que cela (pour une raison quelconque). Cela peut aussi signifier que la tâche est exécutée mais le céleri a oublié son état.

Aie! AsyncResult ne fonctionnera pas pour moi. Que puis-je faire d'autre?

Je préfère garder la trace de objectifs que de suivre les tâches elles-mêmes. Je conserve certaines informations sur les tâches, mais il s’agit en réalité d’une tâche secondaire. Les objectifs sont stockés indépendamment du céleri. Lorsqu'une demande doit effectuer un calcul, cela dépend de la réalisation de l'objectif. Elle vérifie si l'objectif a déjà été atteint. Dans l'affirmative, il utilise cet objectif mis en cache. Dans le cas contraire, il lance la tâche qui va atteindre l'objectif et l'envoie à le client qui a demandé à la requête HTTP une réponse indiquant qu'il devrait attendre un résultat.


Les noms de variable et les liens hypertexte ci-dessus concernent Celery 4.x. Dans 3.x, les variables et hyperliens correspondants sont les suivants: CELERY_TRACK_STARTED , CELERY_IGNORE_RESULT , CELERY_TASK_RESULT_EXPIRES .

45
Louis

Vous pouvez également créer des états personnalisés et mettre à jour sa valeur en exécutant la tâche . Cet exemple est tiré de docs:

@app.task(bind=True)
def upload_files(self, filenames):
    for i, file in enumerate(filenames):
        if not self.request.called_directly:
            self.update_state(state='PROGRESS',
                meta={'current': i, 'total': len(filenames)})

http://celery.readthedocs.org/fr/latest/userguide/tasks.html#custom-states

14
msangel

Vieille question, mais j'ai récemment rencontré ce problème. 

Si vous essayez d'obtenir le task_id, vous pouvez le faire comme ceci: 

import celery
from celery_app import add
from celery import uuid

task_id = uuid()
result = add.apply_async((2, 2), task_id=task_id)

Maintenant vous savez exactement ce qu'est le task_id et vous pouvez maintenant l'utiliser pour obtenir AsyncResult

# grab the AsyncResult 
result = celery.result.AsyncResult(task_id)

# print the task id
print result.task_id
09dad9cf-c9fa-4aee-933f-ff54dae39bdf

# print the AsyncResult's status
print result.status
SUCCESS

# print the result returned 
print result.result
4
9
Cesar Rios

Il suffit d’utiliser cette API à partir de céleri FAQ

result = app.AsyncResult(task_id)

Cela fonctionne bien.

1
David Ding

pour des tâches simples, nous pouvons utiliser http://flower.readthedocs.io/en/latest/screenshots.html et http://policystat.github.io/jobtastic/ pour effectuer la surveillance. 

et pour les tâches compliquées, dites une tâche qui traite beaucoup d'autres modules. Nous vous recommandons d’enregistrer manuellement la progression et le message sur l’unité de tâche spécifique.

0
taotao.li

En dehors de l'approche ci-dessus par programmation Utilisation de Flower Le statut peut être facilement vu.

Surveillance en temps réel à l'aide d'événements de céleri . Flower est un outil Web de surveillance et d'administration des grappes de céleri.

  1. Progression de la tâche et historique
  2. Possibilité d'afficher les détails de la tâche (arguments, heure de début, durée d'exécution, etc.) 
  3. Graphes et statistiques

Document officiel: Fleur - Outil de surveillance du céleri

Installation:

$ pip install flower

Usage:

http://localhost:5555
0
Roshan Bagdiya

J'ai trouvé des informations utiles dans le

Guide des travailleurs du projet Celery inspecting-workers

En ce qui me concerne, je vérifie si le céleri fonctionne. 

inspect_workers = task.app.control.inspect()
if inspect_workers.registered() is None:
    state = 'FAILURE'
else:
    state = str(task.state) 

Vous pouvez jouer avec inspect pour obtenir vos besoins.

0
zerocog