12

如果我创建一个 celery beat 时间表,使用timedelta(days=1),第一个任务将在 24 小时后执行,引用 celery beat 文档:

使用 timedelta 作为计划意味着任务将以 30 秒的间隔发送(第一个任务将在 celery beat 开始后 30 秒发送,然后在最后一次运行后每 30 秒发送一次)。

但事实是,在很多情况下,调度程序在启动时运行任务实际上很重要,但是我没有找到允许我在 celery 启动后立即运行任务的选项,是我没有仔细阅读,还是芹菜缺少这个功能吗?

4

3 回答 3

4

我决定我可以声明每个任务的一个实例,并在 celery 启动时执行它们。我根本不喜欢这个,因为它使启动 celery 节拍非常慢(如果你有 slow 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! ########
于 2015-07-18T07:30:07.120 回答
1

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

于 2021-07-20T09:04:55.170 回答
-1

最好的想法是创建一个实现,在完成任务后安排任务本身。另外,创建一个入口锁,这样该任务就不能每时执行多次。触发执行一次。

在这种情况下,

  • 你不需要 celerybeat 进程
  • 任务保证执行
于 2015-06-15T21:06:34.713 回答