我试图安排一份工作每分钟开始。
我在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()的参数传递。
答案 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()
,方便装饰者。
我会建议这样的事情:
my_scheduler.py
。scheduler.start()
。__init__.py
行
按如下方式更改主文件:
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
)
...