Python 如何使用 APScheduler 安排间隔作业?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29223222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 04:14:09  来源:igfitidea点击:

How do I schedule an interval job with APScheduler?

pythonapscheduler

提问by Troy

I'm trying to schedule an interval job with APScheduler (v3.0.0).

我正在尝试使用 APScheduler (v3.0.0) 安排间隔作业。

I've tried:

我试过了:

from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()

def my_interval_job():
    print 'Hello World!'
sched.add_job(my_interval_job, 'interval', seconds=5)
sched.start()

and

from apscheduler.schedulers.blocking import BlockingScheduler
sched = BlockingScheduler()

@sched.scheduled_job('interval', id='my_job_id', seconds=5)
def my_interval_job():
    print 'Hello World!'
sched.start()

Either should work according to the docs, but the job never fires...

要么应该根据文档工作,但工作永远不会触发......


UPDATE:
It turns out there was something else, environment-related, preventing the task from running. This morning, the task is working fine without any modifications to the code from yesterday.


更新:
事实证明还有其他与环境相关的东西阻止了任务运行。今天早上,任务运行良好,没有对昨天的代码进行任何修改。


UPDATE 2:
After further testing, I've found that 'interval' jobs seem to be generally flaky... The above code now works in my dev environment, but not when I deploy to a staging env (I'm using a heroku app for staging). I have other apscheduler 'cron' jobs that work just fine in the staging/production envs.


更新 2:
经过进一步测试,我发现“间隔”作业似乎通常很不稳定……上面的代码现在可以在我的开发环境中运行,但在我部署到暂存环境时却不能运行(我正在使用 heroku用于登台的应用程序)。我还有其他 apscheduler 'cron' 工作,它们在登台/生产环境中工作得很好。

When I turn on DEBUG logging for the "apscheduler.schedulers" logger, the log indicates that the interval job is added:

当我为“apscheduler.schedulers”记录器打开调试日志时,日志表明添加了间隔作业:

Added job "my_cron_job1" to job store "default"
Added job "my_cron_job2" to job store "default"
Added job "my_interval_job" to job store "default"
Scheduler started
Adding job tentatively -- it will be properly scheduled when the scheduler starts
Adding job tentatively -- it will be properly scheduled when the scheduler starts
Looking for jobs to run
Next wakeup is due at 2015-03-24 15:05:00-07:00 (in 254.210542 seconds)

将作业“my_cron_job1”添加到作业存储“default” 将
作业“my_cron_job2 ”添加到作业存储“default” 将
作业“my_interval_job”添加到作业存储“default”
调度程序开始
临时添加作业——它将在调度程序开始时正确调度
添加暂定作业——它将在调度程序开始时正确安排
寻找要运行的作业
下次唤醒时间为 2015-03-24 15:05:00-07:00(254.210542 秒

How can the next wakeup be due 254 seconds from now when the interval job is set to 5 seconds??

当间隔作业设置为 5 秒时,下一次唤醒如何在 254 秒后到期?

回答by Alex Gr?nholm

The documentation had an error there. I've fixed it now. That first line should be:

那里的文档有错误。我现在已经修好了。第一行应该是:

from apscheduler.schedulers.blocking import BlockingScheduler

It would've raised an ImportError though, but you didn't mention any. Did you try any of the provided examples?

虽然它会引发 ImportError ,但你没有提到任何。您是否尝试过任何提供的示例

回答by Troy

I haven't figured out what caused the original issue, but I got around it by swapping the order in which the jobs are scheduled, so that the 'interval' job is scheduled BEFORE the 'cron' jobs.

我还没有弄清楚是什么导致了最初的问题,但我通过交换作业安排的顺序来解决这个问题,以便在“cron”作业之前安排“间隔”作业。

i.e. I switched from this:

即我从这个切换:

def my_cron_job1():
    print "cron job 1"

def my_cron_job2():
    print "cron job 2"

def my_interval_job():
    print "interval job"

if __name__ == '__main__':
    from apscheduler.schedulers.blocking import BlockingScheduler
    sched = BlockingScheduler(timezone='MST')

    sched.add_job(my_cron_job1, 'cron', id='my_cron_job1', minute=10)
    sched.add_job(my_cron_job2, 'cron', id='my_cron_job2', minute=20)

    sched.add_job(my_interval_job, 'interval', id='my_job_id', seconds=5)

to this:

对此:

def my_cron_job1():
    print "cron job 1"

def my_cron_job2():
    print "cron job 2"

def my_interval_job():
    print "interval job"

if __name__ == '__main__':
    from apscheduler.schedulers.blocking import BlockingScheduler
    sched = BlockingScheduler(timezone='MST')

    sched.add_job(my_interval_job, 'interval', id='my_job_id', seconds=5)

    sched.add_job(my_cron_job1, 'cron', id='my_cron_job1', minute=10)
    sched.add_job(my_cron_job2, 'cron', id='my_cron_job2', minute=20)

and now both the cron jobs and the interval jobs run without a problem in both environments.

现在,cron 作业和间隔作业在两种环境中都可以正常运行。

回答by Alex Gr?nholm

Ok, I've looked at the updated question.

好的,我已经查看了更新的问题。

The reason you're having problems may be that you could be using the wrong timezone. Your country is currently using daylight saving time in most locations, so the correct timezone would probably be MDT (Mountain Daylight Time). But that will break again when you move back to standard time. So I advise you to use a timezone like "America/Denver". That will take care of the DST switches.

您遇到问题的原因可能是您使用了错误的时区。您所在的国家/地区目前在大多数地方都使用夏令时,因此正确的时区可能是 MDT(山地夏令时)。但是当你回到标准时间时,这会再次中断。所以我建议你使用像“美国/丹佛”这样的时区。这将处理 DST 开关。

Question: Are you using CentOS? So far it's the only known operating system where automatic detection of the local timezone is impossible.

问题:您使用的是 CentOS 吗?到目前为止,它是唯一一个无法自动检测本地时区的已知操作系统。

回答by Riaan Steyn

You need to keep the thread alive. Here is a example of how I used it.

您需要保持线程处于活动状态。这是我如何使用它的示例。

from subprocess import call

import time
import os

from apscheduler.schedulers.background import BackgroundScheduler


def job():
    print("In job")
    call(['python', 'scheduler/main.py'])


if __name__ == '__main__':
    scheduler = BackgroundScheduler()
    scheduler.configure(timezone=utc)
    scheduler.add_job(job, 'interval', seconds=10)
    scheduler.add
    scheduler.start()
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))

    try:
        # This is here to simulate application activity (which keeps the main thread alive).
        while True:
            time.sleep(5)
    except (KeyboardInterrupt, SystemExit):
        # Not strictly necessary if daemonic mode is enabled but should be done if possible
        scheduler.shutdown()

回答by Amirkhm

How can the next wakeup be due 254 seconds from now when the interval job is set to 5 seconds??

当间隔作业设置为 5 秒时,下一次唤醒如何在 254 秒后到期?

It's simple: you have many pending executions as your most of the jobs didn't completed in the interval-window of time.

这很简单:您有许多待处理的执行,因为您的大部分工作都没有在时间间隔窗口内完成。

You could use the following parameters in order to sort this out:

您可以使用以下参数来解决这个问题:

 **misfire_grace_time**:    Maximum time in seconds for the job execution to be allowed to delay before it is considered a misfire 
 **coalesce**:  Roll several pending executions of jobs into one

To read more, check the documentation here.

要了解更多信息,请查看此处的文档。