代码在这里。
我编写了celery.schedules.schedule
接口的扩展,但我不明白为什么它在我创建的额外值中没有设置任何值的情况下被实例化。
当我在传递给app.conf.CELERYBEAT_SCHEDULE
之前实例化它们时,它们是正确的。但是,所有那些芹菜打败的即食食品都是不正确的。
我在#celenic IRC-chan中询问过,得到的唯一回复是关于懒惰模式,但这是针对celery.beat.Scheduler
的,而不是celery.schedules.schedule
的,所以如果它相关,我不明白是怎么回事。我是否也必须扩展它,以便它正确地实例化时间表?
我试着用调试器挖掘芹菜代码,找出这些调度在哪里被实例化,但我找不到。我可以看到它们从Unpickler
返回时是错误的,但我无法找到它们在哪里被创建或在哪里被腌制。
celery.schedules.schedule
有一个__reduce__
方法,该方法定义了如何使用pickle:序列化和重构对象
https://github.com/celery/celery/blob/master/celery/schedules.py#L150-L151
pickle序列化对象时将调用:
fun, args = obj.__reduce__()
当它重建物体时,它会做:
obj = fun(*args)
因此,如果您已将新状态添加到自定义计划子类中,并作为参数传递给__init__
,那么您将还必须定义一个__reduce__
方法考虑到新的论点:
class myschedule(schedule):
def __init__(self, run_every=None, relative=False, nowfun=None,
odds=None, max_run_every=None, **kwargs):
super(myschedule, self).__init__(
run_every, relative, nowfun, **kwargs)
self.odds = odds
self.max_run_every = max_run_every
def __reduce__(self):
return self.__class__, (
self.run_every, self.relative, self.nowfun,
self.odds, self.max_run_every)
在Python调试器中花了很多时间后,我将问题缩小到了celener.beat.PersistentScheduler.sync()和/或shelve.sync(由前者调用)。
同步搁置时,值会丢失。我不知道为什么,但我很确定这是Celery或Shelve的错误。
无论如何,我写了一个变通办法。