web-dev-qa-db-fra.com

Révoquer une tâche du céleri

Je souhaite révoquer explicitement une tâche du céleri. Voici comment je fais actuellement: -

from celery.task.control import revoke

revoke(task_id, terminate=True)

où task_id est string (ont également essayé de le convertir en UUID uuid.UUID(task_id).hex).

Après la procédure ci-dessus, lorsque je redémarre le céleri celery worker -A proj, Il consomme toujours le même message et commence à le traiter. Pourquoi?

Lorsqu'il est affiché via flower, le message est toujours là dans la section courtier. comment supprimer le message pour qu'il ne puisse plus être consommé?

18
PythonEnthusiast

Comment fonctionne revoke?

Lorsque vous appelez la méthode revoke, la tâche n'est pas supprimée immédiatement de la file d'attente, elle ne fait que dire au céleri (pas à votre courtier!) D'enregistrer le task_id dans une mémoire set (regardez ici si vous aimez lire le code source comme moi).

Lorsque la tâche arrive en haut de la file d'attente, Celery vérifie si elle se trouve dans l'ensemble révoqué, si c'est le cas, elle ne l'exécute pas.

Cela fonctionne de cette façon pour empêcher O(n) rechercher pour chaque appel revoke, où vérifier si le task_id est dans l'ensemble en mémoire est juste O (1)

Pourquoi après avoir redémarré le céleri, vos tâches révoquées ont été exécutées?

Comprenant comment les choses fonctionnent, vous savez maintenant que le set est juste un ensemble normal python, qui est enregistré en mémoire - cela signifie que lorsque vous redémarrez, vous perdez cet ensemble, mais la tâche est (bien sûr) la persistance et lorsque les tâches arrivent, elle sera exécutée normalement.

Que pouvez-vous faire?

Vous aurez besoin d'un ensemble de persistance, cela se fait en initialisant votre travailleur comme ceci:

celery worker -A proj --statedb=/var/run/celery/worker.state

Cela sauvera l'ensemble sur le système de fichiers.

Références:

29
Or Duan