At the moment djcelery allows me to schedule a recurring task via the PeriodicTask model. For example a task that runs on an interval like every minute, or an interval specified by a crontab like every 1st of the month at noon. What I'd really like to do however is schedule a task for a fixed date that then repeats on an interval. For example first run on 3 March 2016 at 2:00 and then every hour thereafter.
Is there a way to achieve this within django and celery(with or without djcelery)? Thanks
As it is stated in the docs, you may implement your own custom scheduler. You should override the is_due
method, which decides whether it is time to run the task.
Below is a proof-of-concept (I haven't checked it for errors). Note, that the __reduce__
method is also overridden so that the new parameter gets serialised as well.
import celery.schedules.schedule
class myschedule(celery.schedules.schedule):
def __init__(self, *args, **kwargs):
super(myschedule, self).__init__(*args, **kwargs)
self.start_date = kwargs.get('start_date', None)
def is_due(self, last_run_at):
if self.start_date is not None and self.now() < self.start_date:
return (False, 20) # try again in 20 seconds
return super(myschedule, self).is_due(last_run_at)
def __reduce__(self):
return self.__class__, (self.run_every, self.relative, self.nowfun, self.start_date)
And then you use it in the config:
CELERYBEAT_SCHEDULE = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': myschedule(timedelta(seconds=30), start_date=start_date),
'args': (16, 16)
},
}