0

Will this work correctly?

CELERYBEAT_SCHEDULE = {
    'task-number-one': {
        'task': 'project.users.tasks.send_something',
        'schedule': crontab(minute='*/2880'),
    }
}
paolo
  • 101
  • 1
  • 1

2 Answers2

3

No, this will not work. Minutes may only be subdivisions of an hour and don't consider time frames longer then one hour.

In real cron syntax, this would work:

2 2 */2 * *  do_something   
## run every 2nd day at 2:02

Read the docs to learn how this translates into the syntax of Celery.

Note though: This always resets at the beginning of the month, so at the end of months with either 29 or 31 days, it will run again already after 24 hours.

Sven
  • 97,248
  • 13
  • 177
  • 225
1

I don't know every cron implementation but generally the / character can be used to introduce a step but steps don't wrap beyond the end of a series.

i.e. for minutes the series is only 0,1,2,3, ... 59. And actually only steps up to 30 would make any sense as a step of */31 would be the same as specify *"run at minute 31" and the same for every other integer between 31-59.

So minute='*/2880' won't work as you intend.

To deal with odd schedules one option is to run your batch (much) more frequently and simply let the batch itself detect if the minimum interval between successive runs has passed:

In bash that would look something like something like:

#!/bin/bash
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
    echo "The minimum interval of 7 minutes between successive batches hasn't passed yet."
    exit
fi

echo "Start running your batch"

date > /tmp/lastrun

Which you can then safely (attempt) to run every minute:

* * * * * /path/to/your/job

Please see this old answer of mine with this and other strategies on how to deal with odd schedules in cron.

HBruijn
  • 72,524
  • 21
  • 127
  • 192