芹菜自动重新加载任何变化

Ahm*_*DAL 19 python celery django-celery

我可以做芹菜自动重新加载本身时,有在模块的变化CELERY_IMPORTSsettings.py.

我试图让母模块检测甚至在子模块上的变化,但它没有检测到子模块的变化.这让我明白芹菜不能递归检测.我在文档中搜索了它,但我没有遇到任何对我的问题的回应.

在我的项目中添加与celery相关的所有内容CELERY_IMPORTS以检测更改时,我真的很烦.

有没有办法告诉芹菜"当项目的任何地方有任何变化时自动重新加载".

谢谢!

Ora*_*Tux 16

您可以手动包含其他模块-I|--include.与GNU工具,如结合这findawk你就可以找到所有.py文件,包括他们.

$ celery -A app worker --autoreload --include=$(find . -name "*.py" -type f | awk '{sub("\./",""); gsub("/", "."); sub(".py",""); print}' ORS=',' | sed 's/.$//')
Run Code Online (Sandbox Code Playgroud)

让我们解释一下:

find . -name "*.py" -type f
Run Code Online (Sandbox Code Playgroud)

find递归搜索包含的所有文件.py.输出看起来像这样:

./app.py
./some_package/foopy
./some_package/bar.py
Run Code Online (Sandbox Code Playgroud)

然后:

awk '{sub("\./",""); gsub("/", "."); sub(".py",""); print}' ORS=','
Run Code Online (Sandbox Code Playgroud)

该行将输出find作为输入并删除所有出现的./.然后/用一个替换所有..最后一次sub()删除替换.py为空字符串.ORS替换所有换行符,.这输出:

app,some_package.foo,some_package.bar,
Run Code Online (Sandbox Code Playgroud)

最后一个命令,sed删除最后一个,.

所以正在执行的命令如下所示:

$ celery -A app worker --autoreload --include=app,some_package.foo,some_package.bar
Run Code Online (Sandbox Code Playgroud)

如果virtualenv您有源内部,可以通过添加-path .path_to_your_env -prune -o以下内容将其排除:

$ celery -A app worker --autoreload --include=$(find . -path .path_to_your_env -prune -o -name "*.py" -type f | awk '{sub("\./",""); gsub("/", "."); sub(".py",""); print}' ORS=',' | sed 's/.$//')
Run Code Online (Sandbox Code Playgroud)

  • 似乎从版本`4.0`开始,`--autoreload`功能[已被删除](http://docs.celeryproject.org/en/latest/whatsnew-4.0.html?highlight=autoreload#features-removed-缺乏资金):( (5认同)

Chi*_*and 8

芹菜--autoreload不起作用,不推荐使用

由于您正在使用django,因此您可以为此编写管理命令。Django具有autoreload实用程序,当代码更改时,runserver使用它来重新启动WSGI服务器。

可以使用相同的功能来重新加载芹菜工人。创建一个单独的管理命令,称为celery。编写一个函数来杀死现有的工作人员并开始新的工作人员。现在,按如下所示将此函数挂接以自动重新加载。

import shlex
import subprocess

from django.core.management.base import BaseCommand
from django.utils import autoreload


def restart_celery():
    cmd = 'pkill celery'
    subprocess.call(shlex.split(cmd))
    cmd = 'celery worker -l info -A foo'
    subprocess.call(shlex.split(cmd))


class Command(BaseCommand):

    def handle(self, *args, **options):
        print('Starting celery worker with autoreload...')

        # For Django>=2.2
        autoreload.run_with_reloader(restart_celery) 

        # For django<2.1
        # autoreload.main(restart_celery)
Run Code Online (Sandbox Code Playgroud)

现在,您可以运行celery worker,通过python manage.py celery它可以在代码库更改时自动重新加载。

这仅用于开发目的,请勿在生产中使用。代码来自我在这里的其他答案

  • 如果您使用的是Django 2.2+,则`autoreload.main()`已被删除。使用`autoreload.run_with_reloader(restart_celery)`代替。 (6认同)

小智 8

您可以使用 watchmedo

pip install watchdog
Run Code Online (Sandbox Code Playgroud)

通过 watchmedo 间接启动 celery worker

watchmedo auto-restart --directory=./ --pattern=*.py --recursive -- celery worker --app=worker.app --concurrency=1 --loglevel=INFO
Run Code Online (Sandbox Code Playgroud)

更详细