0
votes

How do I schedule a task to run when I start celery beat then again in 1 hours and so.

Currently I have schedule in settings.py:

CELERYBEAT_SCHEDULE = {
    'update_database': {
        'task': 'myapp.tasks.update_database',
        'schedule': timedelta(seconds=60),
    },
}

I saw a post from 1 year here on stackoverflow asking the same question: How to run celery schedule instantly?

However this does not work for me, because my celery worker get 3-4 requests for the same task, when I run django server

I'm starting my worker and beat like this:

celery -A dashboard_web worker -B --loglevel=INFO --concurrency=10
2
Did you find solution? - Danila Ganchar

2 Answers

2
votes

Crontab schedule

You could try to use a crontab schedule instead which will run every hour and start 1 min after initialization of the scheduler. Warning: you might want to do it a couple of minutes later in case it takes longer to start, otherwise you might need to wait the full hour.

from celery.schedules import crontab
from datetime import datetime

CELERYBEAT_SCHEDULE = {
    'update_database': {
        'task': 'myapp.tasks.update_database',
        'schedule': crontab(minute=(datetime.now().minute + 1) % 60),
    },
}

Reference: http://docs.celeryproject.org/en/latest/userguide/periodic-tasks.html#crontab-schedules

Ready method of MyAppConfig

In order to ensure that your task is run right away, you could use the same method as before to create the periodic task without adding 1 to the minute. Then, you call your task in the ready method of MyAppConfig which is called whenever your app is ready.

#myapp/apps.py

class MyAppConfig(AppConfig):
    name = "myapp"

    def ready(self):
        from .tasks import update_database
        update_database.delay()

Please note that you could also create the periodic task directly in the ready method if you were to use django_celery_beat.

Edit: Didn't see that the second method was already covered in the link you mentioned. I'll leave it here in case it is useful for someone else arriving here.

1
votes

Try setting the configuration parameter CELERY_ALWAYS_EAGER = True

Something like this

app.conf.CELERY_ALWAYS_EAGER = True