如果我创建一个芹菜节拍时间表,使用 timedelta(days=1)
,第一个任务将在 24 小时后执行,引用芹菜节拍文档:
对计划使用时间增量意味着任务将以 30 秒的间隔发送(第一个任务将在芹菜节拍开始后 30 秒发送,然后在最后一次运行后每 30 秒发送一次)。
但事实是,在很多情况下,调度程序在启动时运行任务实际上很重要,但是我没有找到允许我在芹菜开始后立即运行任务的选项,是我没有仔细阅读,还是芹菜缺少此功能?
我决定可以声明每个任务的一个实例,并在芹菜发布时执行它们。我一点也不喜欢这样,因为它使芹菜的开始节奏非常慢(如果你的PeriodicTask
慢),但它可以做我想做的。
只需将其添加到tasks.py
末尾:
########### spawn all tasks at launch! ############
localmess = locals().values()
for obj in localmess:
if isclass(obj):
if obj is not PeriodicTask and issubclass(obj, PeriodicTask):
instance = obj()
logger.info('running {0}'.format(obj))
try:
instance.run()
except:
logger.warn('task fail: {0}'.format(obj))
pass
######## all tasks must be decleared above! ########
您可以在工作人员准备好使用worker_ready.connect
装饰器时立即运行任务:
from celery.signals import worker_ready
@worker_ready.connect
def at_start(sender, **kwargs):
"""Run tasks at startup"""
with sender.app.connection() as conn:
sender.app.send_task("app.module.task", connection=conn)
学分归于这个答案:https://stackoverflow.com/a/14589445/3922534
最好的主意是创建一个在完成任务后调度任务本身的实现。此外,创建一个入口锁,以便任务无法每刻多次执行。触发执行一次。
在这种情况下,
- 你不需要芹菜节拍过程
- 保证任务执行