web-dev-qa-db-fra.com

État de la tâche de céleri toujours en attente

Je suis assez nouveau pour le céleri et Django en général, alors veuillez excuser mon manque de connaissances. J'essaie de faire un test pour faire des calculs et d'attendre la fin du test pour pouvoir m'assurer qu'il est bien préparé pour les bonnes réponses.

Voici ce que j'ai:

Dans app/tests.py

from tasks import *


c = calculate.apply_async(args=[1])

# wait until the task is done
while not calculate.AsyncResult(c.id).status == "SUCCESS":
    print c.state
    pass

dans app/tasks.py

from celery import shared_task

@shared_task
def calculate(proj_id):

    #some calculations followed by a save of the object

L'état ne change jamais de l'attente même si, dans le journal du céleri, il est indiqué que la tâche s'est terminée avec succès

[2014-06-10 17:55:11,417: INFO/MainProcess] Received task: app.tasks.calculate[1f11e7ab-0add-42df-beac-3d94c6868aac]
[2014-06-10 17:55:11,505: INFO/MainProcess] Task app.tasks.calculate[1f11e7ab-0add-42df-beac-3d94c6868aac] succeeded in 0.0864518239978s: None

J'ai aussi mis CELERY_IGNORE_RESULT = False dans le fichier mainapp/settings.py, mais cela ne semble rien avoir fait.

16
DoctorWizard

Donc, vos paramètres sont faux. :) Vous devez également configurer un courtier pour que le céleri fonctionne.

Tout d’abord, djcelery est obsolète, tout est inclus dans celery pour que cela fonctionne avec Django.

Deuxièmement, ne définissez pas tous les contenus comme acceptés, cela peut constituer un risque potentiel pour la sécurité. Utilisez pickle uniquement au cas où cette simple json ne suffirait pas (supposons que vous transmettiez des fonctions ou des objets comme arguments à des tâches ou que vous reveniez de tâches)

Donc, je suppose que vous essayez juste le céleri, c'est pourquoi vous essayez d'utiliser une base de données, ce qui est correct, mais pour une utilisation en production, je recommanderais d'utiliser RabbitMQ.

Dans tous les cas, essayez avec ces paramètres:

BROKER_URL = 'Django://'
INSTALLED_APPS = (
    ...
    'kombu.transport.Django', 
    ...
)
CELERY_RESULT_BACKEND = 'db+scheme://user:password@Host:port/dbname' 
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_IGNORE_RESULT = False # this is less important

puis lancez python manage.py syncdb

Juste pour vous faire savoir, je n'ai pas utilisé de base de données en tant que courtier ou résultat, la configuration peut donc être incomplète, voire incorrecte, mais essayez quand même.

plus de réglage CELERY_RESULT_BACKEND pour les exemples de base de données

Si vous souhaitez configurer RabbitMQ en tant que courtier backend, je le recommande et je suis sûr que cela fonctionnera:

si sur Ubuntu, courez:

Sudo apt-get install rabbitmq-server
Sudo rabbitmqctl add_user <username> <password>
Sudo rabbitmqctl add_vhost <vhost, use project name for example>
Sudo rabbitmqctl set_permissions -p <vhost> <username"> ".*" ".*" ".*"

Configurez ensuite le céleri dans settings.py:

BROKER_URL = 'amqp://<user>:<password>@localhost:5672/<vhost>'
CELERY_TIMEZONE = TIME_ZONE
CELERY_RESULT_BACKEND = 'amqp'
# thats where celery will store scheduled tasks in case you restart the broker:
CELERYD_STATE_DB = "/full/path/data/celery_worker_state" 
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

Dites-moi comment ça se passe.

6
lehins

Tout droit de la doc: Résultat backend ne fonctionne pas ou les tâches sont toujours dansEN ATTENTEétat.

Toutes les tâches sont PENDING par défaut, donc l'état aurait été mieux nommé "inconnu". Le céleri ne met à jour aucun état lorsqu'une tâche est envoyée, et toute tâche sans historique est supposée être en attente (vous connaissez la tâche id après tout).

  1. Assurez-vous que ignore_result n'est pas activé pour la tâche.

    L'activation de cette option obligera le travailleur à ignorer les états de mise à jour. 

  2. Assurez-vous que le paramètre CELERY_IGNORE_RESULT n'est pas activé.

  3. Assurez-vous de ne pas avoir d'anciens travailleurs en cours d'exécution.

    Il est facile de démarrer plusieurs travailleurs par accident. Assurez-vous donc que le travailleur précédent est correctement arrêté avant de commencer un nouveau.

    Un ancien travailleur qui n'est pas configuré avec le résultat attendu devrait être en cours d'exécution et détourner les tâches.

    L’argument –pidfile peut être défini sur un chemin absolu pour s’assurer que cela ne se produit pas.

  4. Assurez-vous que le client est configuré avec le bon backend.

Si, pour une raison quelconque, le client est configuré pour utiliser un backend différent de celui de l'opérateur, vous ne pourrez pas recevoir le résultat. Assurez-vous donc que le backend est correct en l'insérant:

>>> result = task.delay(…)
>>> print(result.backend)
9
noooooooob

Si vous utilisez les anciens Django-celery et RabbitMQ comme résultat, ces paramètres peuvent vous aider:

# Mostly, all settings are the same as in other answers

CELERY_RESULT_BACKEND = 'rpc://'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_IGNORE_RESULT = False

# This line is what I needed
CELERY_TRACK_STARTED = True
0
Denis Krumko