web-dev-qa-db-ja.com

Django and Celery-変更後のコードのCeleryへの再ロード

セロリの実行中にtasks.pyを変更した場合、更新されたコードを再ロードできるメカニズムはありますか?または、セロリをリロードしてシャットダウンする必要がありますか?

セロリには--autoreload引数は古いバージョンですが、現在のバージョンでは見つかりません。

celery: error: unrecognized arguments: --autoreload

19
JasonGenX

残念ながら--autoreloadは機能せず、 非推奨 です。

WatchmedoにShellユーティリティを提供するWatchdogを使用して、ファイルイベントに基づいてアクションを実行できます。

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サーバーを再起動するrunserver。

同じ機能を使用して、セロリ労働者をリロードできます。セロリと呼ばれる別の管理コマンドを作成します。既存のワーカーを強制終了し、新しいワーカーを開始する関数を作成します。次のように、この関数をフックして自動リロードします。 Django> = 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))

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

これで、コードベースが変更されたときに自動リロードするpython manage.py celeryでセロリワーカーを実行できます。

これは開発目的のみであり、実稼働では使用しません。

33
ChillarAnand

参考までに、Dockerを使用している人にとっては、上記のオプションを機能させる簡単な方法は見つかりませんでしたが、(他の人と一緒に)別の小さなスクリプトを見つけました here これはwatchdogを使用して完全に動作します。

メインディレクトリーにsome_name.pyファイルとして保存し、pip install psutilとwatchdogをrequirements.txtに追加し、上部のpath/cmdline変数を更新してから、docker-compose.ymlのワーカーコンテナーで挿入します:

command: python ./some_name.py
2
Ryan Skene

親ワーカープロセスでSIGHUPを試してみて、ワーカーを再起動できますが、新しいタスクを取得するかどうかはわかりません。価値があるショット、と思った:)

1
ACimander