【问题标题】:Running tasks in Django Celery at specified time?在指定时间在 Django Celery 中运行任务?
【发布时间】:2020-03-20 16:49:57
【问题描述】:

我的 tasks.py 文件中的片段如下:

from celery.task.schedules import crontab
from celery.decorators import periodic_task

@periodic_task(
    run_every=crontab(minute='15, 45', hour='0, 7, 15'),
)
def task1():
    send_mail()

我希望 task1() 中的脚本仅在 00:157:1515 时触发: 45,而当前设置在 00:1500:457:15 触发7:4515:1515:45

我该怎么做?另外,如果有更好的方法,请告诉我!

【问题讨论】:

  • 可以多次使用装饰器来达到你想要的效果吗?
  • @voodoo-burger 您的意思是多次使用相同的装饰器(使用不同的参数)?那不行!!

标签: python django celery scheduled-tasks


【解决方案1】:

看完documentation,借鉴here的一些想法,我解决了这个问题:

  1. 移除 periodic_task 装饰器并更新 tasks.py 如:

    from celery.task.schedules import crontab
    from celery.decorators import periodic_task
    
    @task
    def task1():
        send_mail()
    
  2. celery.py 中添加 beat schedule 为:

    app.conf.beat_schedule = {
        'alert': {
            'task': 'app.tasks.task1',
            'schedule': crontab(minute='15', hour='0, 7')
        },
        'custom_alert': {
            'task': 'app.tasks.task1',
            'schedule': crontab(minute='45', hour='15')
        }
    }
    

通过这些设置,task1() 中的脚本 只会在所需时间(0:15、7:15 和 15:45)触发! p>

【讨论】:

  • 我认为您不必定义节拍时间表两次。否则这是更好的解决方案。
  • @schillingt 感谢您指出!根据您的建议更新了答案。
【解决方案2】:

你有两个选择。一种是定义装饰函数几次:

def _task1():
    send_mail()

task1_a = @periodic_task(
    _task1,
    run_every=crontab(minute='15', hour='0, 7'),
)
task1_b = @periodic_task(
    _task1,
    run_every=crontab(minute='45', hour='15'),
)

另一种选择是定义实现celery's schedule interface 的自定义计划。

【讨论】:

  • 我认为我们不能将装饰器分配给变量!我正在探索第二种方法,但您能否详细说明第一种方法?
  • 是的,你可以。 Python 是一种具有一流功能的语言。它们本身就是有效的对象。装饰器所做的只是包装内部函数。因此,与其定义内部函数两次或创建一个调用内部函数的新函数,不如使用装饰器两次包装函数创建两个新函数。
  • 虽然我知道 Python 中的一流函数,但我认为不可能以这种方式使用装饰器!至于给定的问题,第一种方法(将装饰器分配给变量的方法)会引发语法错误。
猜你喜欢
  • 2022-11-14
  • 1970-01-01
  • 2020-05-24
  • 2020-06-30
  • 2013-12-16
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多