web-dev-qa-db-fra.com

Django et Céleri - recharger du code dans Céleri après une modification

Si j'apporte une modification à tasks.py pendant que le céleri est en cours d'exécution, existe-t-il un mécanisme permettant de recharger le code mis à jour? ou dois-je arrêter le céleri d'un rechargement?

J'ai lu que le céleri avait un argument --autoreload dans les versions précédentes, mais je ne le trouve pas dans la version actuelle: 

celery: error: unrecognized arguments: --autoreload

17
JasonGenX

Malheureusement, --autoreload ne fonctionne pas et il est obsolète .

Vous pouvez utiliser Watchdog qui fournit à watchmedo un utilitaire Shell permettant d’effectuer des actions en fonction des événements de fichier. 

pip install watchdog

Vous pouvez commencer travailleur avec 

watchmedo auto-restart -- celery worker -l info -A foo

Par défaut, tous les fichiers du répertoire en cours seront surveillés. Ceux-ci peuvent être modifiés en passant les paramètres correspondants.

watchmedo auto-restart -d . -p '*.py' -- celery worker -l info -A foo

Si vous utilisez Django et que vous ne voulez pas dépendre de watchdog, il existe un truc simple pour y parvenir. Django dispose d'un utilitaire de chargement automatique utilisé par runserver pour redémarrer le serveur WSGI lorsque le code change.

La même fonctionnalité peut être utilisée pour recharger des céleris. Créez une commande de gestion séparée appelée céleri. Ecrivez une fonction pour tuer le travailleur existant et démarrer un nouveau travailleur. Maintenant, connectez cette fonction au chargement automatique comme suit.

import sys

import shlex
import subprocess
from Django.core.management.base import BaseCommand
from Django.utils import autoreload


class Command(BaseCommand):
    def handle(self, *args, **options):
        autoreload.main(self._restart_celery)

    @classmethod
    def _restart_celery(cls):
        if sys.platform == "win32":
            cls.run('taskkill /f /t /im celery.exe')
            cls.run('celery -A phoenix worker --loglevel=info --pool=solo')
        else:  # probably ok for linux2, cygwin and darwin. Not sure about os2, os2emx, riscos and atheos
            cls.run('pkill celery')
            cls.run('celery worker -l info -A foo')

    @staticmethod
    def run(cmd):
        subprocess.call(shlex.split(cmd))

Vous pouvez maintenant exécuter celery worker avec python manage.py celery qui se chargera automatiquement lorsque la base de code sera modifiée.

Ceci est uniquement à des fins de développement et ne l'utilisez pas en production.

29
ChillarAnand

Pour votre information, pour ceux qui utilisent Docker, je ne pouvais pas trouver un moyen simple de faire fonctionner les options ci-dessus, mais j’ai trouvé (avec d’autres) un autre petit script ici qui utilise watchdog et fonctionne parfaitement.

Enregistrez-le en tant que fichier some_name.py dans votre répertoire principal, ajoutez pip install psutil et watchdog en requirements.txt, mettez à jour les variables path/cmdline en haut, puis dans le conteneur de travail de votre insertion docker-compose.yml:

command: python ./some_name.py
2
Ry John

Vous pouvez essayer SIGHUP sur le processus de travail parent, il redémarre le travailleur, mais je ne suis pas sûr qu'il récupère de nouvelles tâches. Vaut le coup, pensé :)

1
ACimander