crontab not working with celery multi start - django

I am trying to get Celery work for awhile now. All my crontabs works just fine when I test it synchronously
sudo celery -A testdjango worker --loglevel=DEBUG --beat
but when I do
celery multi start -A testdjango w1 -l info
none of my crontabs work. I am not sure why
Note: I tried other schedule intervals as well like with time delta The same thing happens with that as well.
So I am fairly certain this is not a crontab thing but somehow related to the way I am starting celery multi.
Also, the worker turns on just fine since I can see it in Celery Flower but no tasks get executed.

So, the answer is pretty straightforward
Since periodic tasks need Beat just add --beat with the command.
something like this
celery multi start -A testdjango w1 --beat -l info

Alternatively instead of running Beat inside your worker process (which the docs for 3.1.18 say is not recommended) you can run it dedicated in the background with
celery beat -A testdjango --pidfile=/blah/beat.pid --detach
Be sure to save the pidfile somewhere so you can also kill the process later.

Related

Should I use attach-daemon or smart-attach daemon to autostart celery with UWSGI (and easily update the tasks)

First off - I am aware UWSGI suggest using smart-attach-daemon
from: http://uwsgi-docs.readthedocs.io/en/latest/AttachingDaemons.html
Managing celery:
[uwsgi]
master = true
socket = :3031
smart-attach-daemon = /tmp/celery.pid celery -A tasks worker --pidfile=/tmp/celery.pid
However, it seems when I push updates to the server, Celery tasks are not updated - to make this happen it seems I have do issue killall celery - which it seems would be practically automated by using attach-daemon to start it instead?
Am I missing something here, is there a better solution than either killing celery instances, or using attach-daemon ?
You'd better use attach-daemon, because smart-attach-daemon means that you will manage your smart daemon restarting on your own.
Since uwsgi 2.0 there are also 'attach-daemon2' which have touch option.

celery control add_consumer giving Error: No nodes replied within time constraint

I want to configure celery worker to consume only from a particular queue,
I saw in celery docs that control add_consumer does exactly that.
Problem is when I try :
celery control -A [App_name] add_consumer [queue_name] worker1.h%
it gives me error :
Error: No nodes replied within time constraint
Any help is really appreciated.
Is there any other way I can make my worker consume from a specific queue?
Note : celery -A [App_name] worker1.h%
starts the celery worker, and everything works fine just that is works on all my queues. I want to dedicate a worker to consume from specific queue.
Broker used: rabbitmq
I would just run a separate worker
celery -A app_name -Q queue_name --concurrency=1

scheduling start up doesn't work

When setting-up Celery and I want to use scheduling do I add both init scripts below or just the celerybeat one?
https://github.com/ask/celery/blob/master/contrib/generic-init.d/celeryd
https://raw.github.com/ask/celery/master/contrib/generic-init.d/celerybeat
The issue is I have both scripts and Celery does not run in beat mode and scheduling does not work (normal task do?)
Run:
sh -x /etc/init.d/celeryd start
This should print to screen any errors on startup, from this you should see whats going wrong.

How do I restart celery workers gracefully?

While issuing a new build to update code in workers how do I restart celery workers gracefully?
Edit:
What I intend to do is to something like this.
Worker is running, probably uploading a 100 MB file to S3
A new build comes
Worker code has changes
Build script fires signal to the Worker(s)
Starts new workers with the new code
Worker(s) who got the signal after finishing the existing job exit.
According to https://docs.celeryq.dev/en/stable/userguide/workers.html#restarting-the-worker you can restart a worker by sending a HUP signal
ps auxww | grep celeryd | grep -v "grep" | awk '{print $2}' | xargs kill -HUP
celery multi start 1 -A proj -l info -c4 --pidfile=/var/run/celery/%n.pid
celery multi restart 1 --pidfile=/var/run/celery/%n.pid
http://docs.celeryproject.org/en/latest/userguide/workers.html#restarting-the-worker
If you're going the kill route, pgrep to the rescue:
kill -9 `pgrep -f celeryd`
Mind you, this is not a long-running task and I don't care if it terminates brutally. Just reloading new code during dev. I'd go the restart service route if it was more sensitive.
You can do:
celery multi restart w1 -A your_project -l info # restart workers
Example
You should look at Celery's autoreloading
What should happen to long running tasks? I like it this way: long running tasks should do their job. Don't interrupt them, only new tasks should get the new code.
But this is not possible at the moment: https://groups.google.com/d/msg/celery-users/uTalKMszT2Q/-MHleIY7WaIJ
I have repeatedly tested the -HUP solution using an automated script, but find that about 5% of the time, the worker stops picking up new jobs after being restarted.
A more reliable solution is:
stop <celery_service>
start <celery_service>
which I have used hundreds of times now without any issues.
From within Python, you can run:
import subprocess
service_name = 'celery_service'
for command in ['stop', 'start']:
subprocess.check_call(command + ' ' + service_name, shell=True)
If you're using docker/docker-compose and putting celery into a separate container from the Django container, you can use
docker-compose kill -s HUP celery
, where celery is the container name. The worker will be gracefully restarted and the ongoing task is not brutally stopped.
Tried pkill, kill, celery multi stop, celery multi restart, docker-compose restart. All not working. Either the container is stopped abruptly or the code is not reloaded.
I just want to reload my code in the prod server manually with a 1-liner. Don't want to play with daemonization.
Might be late to the party. I use:
sudo systemctl stop celery
sudo systemctl start celery
sudo systemctl status celery

Issues with celery daemon

We're having issues with our celery daemon being very flaky. We use a fabric deployment script to restart the daemon whenever we push changes, but for some reason this is causing massive issues.
Whenever the deployment script is run the celery processes are left in some pseudo dead state. They will (unfortunately) still consume tasks from rabbitmq, but they won't actually do anything. Confusingly a brief inspection would indicate everything seems to be "fine" in this state, celeryctl status shows one node online and ps aux | grep celery shows 2 running processes.
However, attempting to run /etc/init.d/celeryd stop manually results in the following error:
start-stop-daemon: warning: failed to kill 30360: No such process
While in this state attempting to run celeryd start appears to work correctly, but in fact does nothing. The only way to fix the issue is to manually kill the running celery processes and then start them again.
Any ideas what's going on here? We also don't have complete confirmation, but we think the problem also develops after a few days (with no activity this is a test server currently) on it's own with no deployment.
I can't say that I know what's ailing your setup, but I've always used supervisord to run celery -- maybe the issue has to do with upstart? Regardless, I've never experienced this with celery running on top of supervisord.
For good measure, here's a sample supervisor config for celery:
[program:celeryd]
directory=/path/to/project/
command=/path/to/project/venv/bin/python manage.py celeryd -l INFO
user=nobody
autostart=true
autorestart=true
startsecs=10
numprocs=1
stdout_logfile=/var/log/sites/foo/celeryd_stdout.log
stderr_logfile=/var/log/sites/foo/celeryd_stderr.log
; Need to wait for currently executing tasks to finish at shutdown.
; Increase this if you have very long running tasks.
stopwaitsecs = 600
Restarting celeryd in my fab script is then as simple as issuing a sudo supervisorctl restart celeryd.