pythoncelerydjango-celery

Celery auto reload on ANY changes


I could make celery reload itself automatically when there is changes on modules in CELERY_IMPORTS in settings.py.

I tried to give mother modules to detect changes even on child modules but it did not detect changes in child modules. That make me understand that detecting is not done recursively by celery. I searched it in the documentation but I did not meet any response for my problem.

It is really bothering me to add everything related celery part of my project to CELERY_IMPORTS to detect changes.

Is there a way to tell celery that "auto reload yourself when there is any changes in anywhere of project".

Thank You!


Solution

  • You can manually include additional modules with -I|--include. Combine this with GNU tools like find and awk and you'll be able to find all .py files and include them.

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

    Lets explain it:

    find . -name "*.py" -type f
    

    find searches recursively for all files containing .py. The output looks something like this:

    ./app.py
    ./some_package/foopy
    ./some_package/bar.py
    

    Then:

    awk '{sub("\./",""); gsub("/", "."); sub(".py",""); print}' ORS=','
    

    This line takes output of find as input and removes all occurences of ./. Then it replaces all / with a .. The last sub() removes replaces .py with an empty string. ORS replaces all newlines with ,. This outputs:

    app,some_package.foo,some_package.bar,
    

    The last command, sed removes the last ,.

    So the command that is being executed looks like:

    $ celery -A app worker --autoreload --include=app,some_package.foo,some_package.bar
    

    If you have a virtualenv inside your source you can exclude it by adding -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/.$//')