【问题标题】:Schedule python clear jobs queue安排python清除作业队列
【发布时间】:2023-08-20 00:51:01
【问题描述】:

我正在尝试使用如下时间表:

def job():
   my code

schedule.every().day.at("06:03").do(job)
schedule.every().day.at("09:56").do(job)

while True:
   schedule.run_pending()
   sleep(1)

我的工作不可能需要 1 到 10 个小时才能完成。

我遇到的问题是这样的:

基本上,当第一个作业运行时(在 06:03),如果作业需要大约 10 个小时,那么当它结束时它会再次启动,因为 schedule 会运行它丢失的所有作业(在这种情况下它错过了作业在 09:56,因此它运行)。

但是我想要的是,如果作业需要很长时间,那么它丢失的计划不会立即运行,而是必须从下一个计划重新开始(在示例中为 06:03)。简单来说,如果错过了一个调度,就需要清理“调度队列”,从下一个调度的时间重新开始。不需要运行所有错过的预定时间。

【问题讨论】:

    标签: python scheduled-tasks schedule


    【解决方案1】:

    这是一个满足您需要的准系统解决方案示例,我尽量不进行优化以使其清晰。

    这是一个在结束之前重新安排自己并清除现有实例的作业。

    import time
    import schedule
    
    def job_every_nsec(seconds=10):
        ### Job code
        print("before_job_every_nsec", time.time()) 
        time.sleep(20) 
        print("after_job_every_nsec", time.time())
        ### End of job code 
        # after the code of your job schedule the same job again
        # notice that the functions calls itself (recursion)
        schedule.every(seconds).seconds.do(job_every_nsec, seconds=seconds)
        # and clear the existing one
        return schedule.CancelJob
    
    def job_at(start_at):
        ### Job code
        print("before job_at", time.time()) 
        time.sleep(20) 
        print("after job_at", time.time())
        ### End of job code 
        # after the code of your job schedule the same job again
        schedule.every().day.at(start_at)
        # and clear the existing one
        return schedule.CancelJob
    
    
    # launch jobs for the first time
    schedule.every(10).seconds.do(job_every_nsec, seconds=10)
    schedule.every().day.at("12:30").do(job_at, start_at="12:30")
    
    while True:
        schedule.run_pending()
        time.sleep(1)
    

    【讨论】:

    • 我真的不明白你做了什么。如果我的日程安排在例如 06:00、09:00、13:00 和 17:00 运行作业会怎样。我将如何调整您刚刚发送的代码?
    • 我用at添加了一个例子,希望现在更清楚。关键是函数会在完成之前自行重新调度,因此您需要将触发时间作为参数传递。
    • 哦,好吧,我想我现在明白了。所以基本上你重新安排现有的工作并取消另一个。所以基本上现在我可以设置尽可能多的:``` schedule.every().day.at("06:00").do(job_at, start_at="06:00") schedule.every().day。 at("09:00").do(job_at, start_at="09:00") schedule.every().day.at("13:00").do(job_at, start_at="13:00") ```如我所愿。如果错过了一个作业,它不会在队列中,但它会在第二天再次运行,对吗?
    • 是的,从我的测试来看,行为正是这样。
    • 完美!我会尝试一下,看看它是否适合我。非常感谢!!