Django and Celery - перезагрузка кода в сельдерей после смены

Если я вношу изменения в tasks.py, пока работает сельдерей, есть ли механизм, с помощью которого он может повторно загрузить обновленный код? или мне нужно закрыть сельдерей с повторной загрузкой?

Я читал, что у сельдерея был аргумент --autoreload в более старых версиях, но я не могу найти его в текущей версии:

celery: error: unrecognized arguments: --autoreload

Ответ 1

К сожалению, --autoreload не работает, и он устарел.

Вы можете использовать Watchdog, который обеспечивает watchmedo утилитами оболочки для выполнения действий, основанных на событиях файла.

pip install watchdog

Вы можете начать работать с

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

По умолчанию он будет следить за всеми файлами в текущем каталоге. Их можно изменить, передав соответствующие параметры.

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

Если вы используете django и не хотите зависеть от сторожевого пса, для этого есть простой трюк. В Django есть утилита автозагрузки, которая используется сервером запуска для перезапуска сервера WSGI при изменении кода.

Та же функциональность может быть использована для перезагрузки сельдерея. Создайте отдельную команду управления под названием сельдерей. Напишите функцию для уничтожения существующего работника и запуска нового работника. Теперь подключите эту функцию для автоматической перезагрузки следующим образом. Для Джанго> = 2.2

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.run_with_reloader(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))

Для Джанго <2,2

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))

Теперь вы можете запустить celery worker с помощью python manage.py celery который будет автоматически перезагружаться при изменении кодовой базы.

Это только для целей разработки и не использовать его в производстве.

Ответ 2

FYI, для тех, кто с помощью докер, я не мог найти простой способ сделать выше варианты работы, но я нашел (наряду с другими) еще один маленький скрипт здесь, который делает использование сторожевого и отлично работает.

Сохраните его как some_name.py файла в главной директории, добавить пункт установить psutil и сторожевой requirements.txt, обновить переменные пути/командная_строка в верхней части, а затем в рабочий контейнер вашего Докер-compose.yml вставки:

command: python ./some_name.py

Ответ 3

Вы можете попробовать SIGHUP на родительском рабочем процессе, перезапустить рабочего, но я не уверен, что он поднимает новые задачи. Стоит, подумал:)