【问题标题】:Django celery: scheduling recurring task but with fixed start dateDjango celery:安排重复任务,但开始日期固定
【发布时间】:2016-05-24 11:01:34
【问题描述】:

目前 djcelery 允许我通过 PeriodicTask 模型安排重复任务。例如,一个任务以每分钟的间隔运行,或者由 crontab 指定的间隔,如每个月的第一天中午。然而,我真正想做的是安排一个固定日期的任务,然后每隔一段时间重复一次。例如,在 2016 年 3 月 3 日 2:00 首次运行,然后每隔一小时运行一次。

有没有办法在 django 和 celery 中实现这一点(有或没有 djcelery)?谢谢

【问题讨论】:

    标签: django celery django-celery celery-task


    【解决方案1】:

    正如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)
        },
    }
    

    【讨论】:

    • 谢谢。这很有帮助并且接近我想要的,但是我还需要它作为数据库调度程序(因为目前我有一个前端接口供用户创建 PeriodicTask 模型实例以启动作业)。我想我需要做类似的事情,但也许 celery.beat.Scheduler 被覆盖? (类似于 djcelery 现在在 djcelery.schedulers.DatabaseScheduler 中的做法,但可能会覆盖 is_due 那里?)
    • 是的,数据库后端让事情变得有点复杂。实际上,为了避免教django-celery 使用自定义时间表(如我上面的答案)的混乱,我宁愿更新/覆盖PeriodicTask 模型以包含start_date 字段并覆盖DatabaseScheduler 以便它需要考虑到: ``` class MyScheduler(DatabaseScheduler): def is_due(self, entry): if entry.schedule.now()
    • 哪里是覆盖PeriodicTask 的正确位置?我应该只分叉 djcelery 还是有更好的方法?
    • 或者我想如果我只是覆盖 DatabaseScheduler,我可以在 settings.py 中指向它,在我的 CustomDatabaseScheduler 中,我将 ModelEntry 设置为我的自定义版本..
    • 您可以在不接触 djcelery 的情况下创建自己的模型,并为其添加 start_date 字段。此外,在这种情况下,您需要register the signals。或者,您可以更新 djcelery(PeriodicTaskDatabaseScheduler),因为这看起来很有用。后者对我来说似乎是一个更好的选择。唯一的问题是 djcelery 似乎被放弃了——你的 PR 几乎不会很快通过。
    猜你喜欢
    • 1970-01-01
    • 2011-12-12
    • 2019-07-10
    • 2020-04-05
    • 1970-01-01
    • 2014-02-23
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    相关资源
    最近更新 更多