APScheduler工作未按计划开始

时间:2017-11-20 10:13:41

标签: python django apscheduler

我试图安排一份工作每分钟开始。 我在scheduler.py脚本中定义了调度程序:

from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor


executors = {
    'default': ThreadPoolExecutor(10),
    'processpool': ProcessPoolExecutor(5)
}
job_defaults = {
    'coalesce': False,
    'max_instances': 5
}

scheduler = BackgroundScheduler(executors=executors,job_defaults=job_defaults)

我在模块的__init__.py中初始化调度程序,如下所示:

from scheduler import scheduler

scheduler.start()

我想开始针对特定操作的预定作业,例如:

def AddJob():
    dbid = repository.database.GetDbid()
    job_id = 'CollectData_{0}'.format(dbid)
    scheduler.scheduled_job(func=TestScheduler(),
                            trigger='interval',
                            minutes=1,
                            id=job_id
                            )

def TestScheduler():
    for i in range(0,29):
        starttime = time()
        print "test"
        sleep(1.0 - ((time() - starttime) % 1.0))

首先:当我在python控制台中执行AddJob()函数时,它开始按预期运行但不在后台运行,控制台被阻塞,直到TestScheduler函数在30之后结束秒。我期待它在后台运行,因为它是后台调度程序 第二:即使指定1分钟的重复间隔,作业也不会再次开始。

我错过了什么?

更新

我发现问题归功于另一个线程。错误的是这个:

scheduler.scheduled_job(func=TestScheduler(),
                            trigger='interval',
                            minutes=1,
                            id=job_id
                            )

我把它改为:

scheduler.add_job(func=TestScheduler,
                            trigger='interval',
                            minutes=1,
                            id=job_id
                            )

TestScheduler()成为TestScheduler。使用TestScheduler()导致函数TestScheduler()的结果作为add_job()的参数传递。

1 个答案:

答案 0 :(得分:1)

第一个问题似乎是您正在初始化__init__.py内的调度程序,这似乎不是推荐的方式。
第一次导入特定文件夹中的模块时,__init__.py中存在的代码将被执行。例如,想象一下这个结构:

my_module
|--__init__.py
|--test.py

__init__.py

from scheduler import scheduler

scheduler.start()

scheduler.start()时执行from my_module import something命令。所以它要么从__init__.py开始,要么开始很多次(取决于你的其余代码!)。

另一个问题必须是使用scheduler.scheduled_job()方法。如果您阅读文档on adding jobs,您会发现推荐的方法是使用add_job()方法,而不是scheduled_job(),方便装饰者。

我会建议这样的事情:

  1. 按原样保留my_scheduler.py
  2. scheduler.start()
  3. 中删除__init__.py
  4. 按如下方式更改主文件:

    from my_scheduler import scheduler
    
    if not scheduler.running: # Clause suggested by @CyrilleMODIANO
        scheduler.start()
    
    def AddJob():
        dbid = repository.database.GetDbid()
        job_id = 'CollectData_{0}'.format(dbid)
        scheduler.add_job(
            func=TestScheduler,
            trigger='interval',
            minutes=1,
            id=job_id
        )
    
    ...