48

我在烧瓶应用程序中使用 apscheduler 时遇到问题。

在我的 view.py 文件中,我这样写

import time
from apscheduler.scheduler import Scheduler

def test_scheduler():
     print "TEST"
     print time.time()


sched = Scheduler()
sched.add_interval_job(test_scheduler, seconds=5)
sched.start()

然后这个方法 test_scheduler() 每五秒执行两次

测试 1360844314.01 测试 1360844314.2

4

5 回答 5

68

在调试模式下,Flask 的重新加载器将加载烧瓶应用程序两次(如何停止 Flask 在调试模式下初始化两次?)。我不确定为什么会这样,但它会导致 apscheduler 的作业被安排两次。一个快速的print "loaded scheduler"权利之前sched.start()证实了这一点。

如链接答案中所述,有几种方法可以解决此问题。我发现效果最好的一个就是像这样禁用重新加载器:

app.run(use_reloader=False)

这意味着我必须在开发应用程序时手动重新加载它,但要让 apscheduler 正常工作,这是一个很小的代价。

于 2013-03-19T04:38:34.233 回答
46

使用重载器时,有主进程和子进程。您的调度程序线程在两者中运行。您需要阻止调度程序在主进程中运行

if not app.debug or os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
  sched = Scheduler()
  sched.add_interval_job(test_scheduler, seconds=5)
  sched.start()
于 2014-08-27T05:29:55.923 回答
14

您可以在 Flask 的before_first_request()装饰器中启动调度程序,它“注册一个要在对应用程序实例的第一个请求之前运行的函数”。

import time
import atexit

from apscheduler.schedulers.background import BackgroundScheduler


def print_date_time():
    print(time.strftime("%A, %d. %B %Y %I:%M:%S %p"))


@app.before_first_request
def init_scheduler():
    scheduler = BackgroundScheduler()
    scheduler.add_job(func=print_date_time, trigger="interval", seconds=3)
    scheduler.start()
    # Shut down the scheduler when exiting the app
    atexit.register(lambda: scheduler.shutdown())

请注意,before_first_request()在服务器重新加载后,第一个请求总是会再次调用它。

于 2016-07-21T10:11:07.400 回答
-2

最好的解决方案是使用add_cron_job('*')而不是add_interval_job('*')

于 2013-02-14T13:37:47.040 回答
-3

我做到了,我在 add_interval_job 参数中添加了在某个时间点后开始

sched.add_interval_job(test_scheduler, seconds=5, start_date='2013-02-13 00:00')
于 2013-02-14T13:16:44.920 回答