10
votes

I'm running a site using Django 10, RabbitMQ, and Celery 4 on CentOS 7.

My Celery Beat and Celery Worker instances are controlled by supervisor and I'm using the django celery database scheduler.

I've scheduled a cron style task using the cronsheduler in Django-admin.

When I start celery beat and worker instances the job fires as expected.

But if a change the schedule time in Django-admin then the changes are not picked up unless I restart the celery-beat instance.

Is there something I am missing or do I need to write my own scheduler?

Celery Beat, with the 'django_celery_beat.schedulers.DatabaseScheduler' loads the schedule from the database. According to the following doc https://media.readthedocs.org/pdf/django-celery-beat/latest/django-celery-beat.pdf this should force Celery Beat to reload:

A schedule that runs at a specific interval (e.g. every 5 seconds). • django_celery_beat.models.CrontabSchedule A schedule with fields like entries in cron: minute hour day-of-week day_of_month month_of_year.

django_celery_beat.models.PeriodicTasks This model is only used as an index to keep track of when the schedule has changed. Whenever you update a PeriodicTask a counter in this table is also incremented, which tells the celery beat service to reload the schedule from the database. If you update periodic tasks in bulk, you will need to update the counter manually:

from django_celery_beat.models import PeriodicTasks
PeriodicTasks.changed()

From the above I would expect the Celery Beat process to check the table regularly for any changes.

2
Don't think it is a duplicate as I want Celery Beat to detect when the schedule has been updated in the database.Steve
Definitely, not a duplicated. The linked question is talking about reload celery worker if Django settings change (a static .py file), not about celery beat and reload when database tasks change.Ruben
Looks like this Github issue is a discussion of the same problem: (they reference this post). Some solutions proposed, none simple. Also here. No solution given.Gabriel

2 Answers

2
votes

i have changed the celery from 4.0 to 3.1.25, django to 1.9.11 and installed djcelery 3.1.17. Then test again, It's OK. So, maybe it's a bug.

1
votes

I have a solution by:

  1. Creating a separate worker process that consumes a RabbitMQ queue.
  2. When Django updates the database it posts a message to the queue containing the name of the Celery Beat process (name defined by Supervisor configuration).
  3. The worker process then restarts the named Celery Beat process.

A bit long winded but does the job. Also makes it easier to manage multiple Django apps on the same server that require the same functionality.