Django celery:安排重复任务但开始日期固定
Django celery: scheduling recurring task but with fixed start date
目前,djcelery 允许我通过 PeriodicTask 模型安排重复任务。例如,运行 以每分钟为间隔执行的任务,或者由 crontab 指定的间隔,例如每月 1 号中午。然而,我真正想做的是安排一个固定日期的任务,然后每隔一段时间重复一次。例如,2016 年 3 月 3 日的第一个 运行 2:00,然后每隔一小时。
有没有办法在 django 和 celery(有或没有 djcelery)中实现这一点?谢谢
如 the docs 中所述,您可以实现自己的自定义调度程序。您应该覆盖 is_due
方法,该方法决定是否是 运行 任务的时间。
下面是一个概念验证(我没有检查它是否有错误)。请注意,__reduce__
方法也被覆盖,以便新参数也被序列化。
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)
然后在配置中使用它:
CELERYBEAT_SCHEDULE = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': myschedule(timedelta(seconds=30), start_date=start_date),
'args': (16, 16)
},
}
目前,djcelery 允许我通过 PeriodicTask 模型安排重复任务。例如,运行 以每分钟为间隔执行的任务,或者由 crontab 指定的间隔,例如每月 1 号中午。然而,我真正想做的是安排一个固定日期的任务,然后每隔一段时间重复一次。例如,2016 年 3 月 3 日的第一个 运行 2:00,然后每隔一小时。
有没有办法在 django 和 celery(有或没有 djcelery)中实现这一点?谢谢
如 the docs 中所述,您可以实现自己的自定义调度程序。您应该覆盖 is_due
方法,该方法决定是否是 运行 任务的时间。
下面是一个概念验证(我没有检查它是否有错误)。请注意,__reduce__
方法也被覆盖,以便新参数也被序列化。
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)
然后在配置中使用它:
CELERYBEAT_SCHEDULE = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': myschedule(timedelta(seconds=30), start_date=start_date),
'args': (16, 16)
},
}