問題文:
ジョブストアにジョブを格納するように構成されているメソッド( Test::start()
)を追加しようとしています。ジョブストアへのジョブの追加は成功しました。しかし、スケジューラーを起動しようとすると、(in )は指定されたオブジェクトのを取得できません[この場合、指定されたオブジェクトは-つまり]です。scheduler.add_date_job()
SQLAlchemyJobStore
obj_to_ref
apscheduler/util.py
ref_to_obj()
Test::start()
<bound method Test.start of <__main__.Test instance at 0xa119a6c>>
ただし、次の場合、同じ操作が正常に機能します。
- その他のジョブストア(fe-
RAMJobStore
これは、ジョブストアが追加/構成されていない場合のデフォルトです)。 - が
scheduler.add_date_job()
他の関数(func
以下のコードではfe)で呼び出され、Test::start()
(ジョブストアがSQLAlchemyJobStore
)[the andforis ]のようなメソッドref_to_obj()
ではない場合。同じことを確認するために、いくつかのデバッグを(に)追加しました。obj_to_ref()
func
<function func at 0xb768ed14>
apscheduler/util.py
コードは次のとおりです。
from apscheduler.scheduler import Scheduler as scheduler
from datetime import datetime, date, time, timedelta
import time
import logging
logging.basicConfig(filename='/tmp/log', level=logging.DEBUG,
format='[%(asctime)s]: %(levelname)s : %(message)s')
class Failed(Exception):
def __str__(self):
return 'Failed!!'
# APScheduler Configure Options
_g_aps_default_config = {
'apscheduler.standalone' : True,
'apscheduler.jobstore.default.class' : 'apscheduler.jobstores.sqlalchemy_store:SQLAlchemyJobStore',
'apscheduler.jobstore.default.url' : 'mysql://root:root123@localhost/jobstore',
'apscheduler.jobstore.default.tablename' : 'mytable'
}
class Test:
def __init__(self, *args, **kwargs):
self.scheduler = scheduler(_g_aps_default_config)
self.__running = False
# Intentionally don't want to start!!
self.__dont_start = True
self.__retry_count = 0
self.__start_max_retries = 5
def start(self):
try:
# Try to start here!
# Intentionally don't want to start for the first 5 times
if self.__retry_count < self.__start_max_retries:
self.__retry_count += 1
raise Failed
if self.__running:
raise Failed
self.__running = True
print 'started successfully :)'
except Failed:
# log the start failure and reschedule the start()
print 'attempt (#%d): unable to start now.. ' \
'so rescheduling to start after 5 seconds' % self.__retry_count
alarm_time = datetime.now() + timedelta(seconds=5)
self.scheduler.add_date_job(self.start, alarm_time)
self.scheduler.start()
def func():
print 'this is a func and not a method!!!'
if __name__ == '__main__':
t = Test()
t.start()
while True:
time.sleep(10)
t.stop()
スタックトレースは次のとおりです。
Traceback (most recent call last):
File "user1.py", line 55, in <module>
t.start()
File "user1.py", line 48, in start
self.scheduler.start()
File "/usr/lib/python2.7/site-packages/APScheduler-2.1.0-py2.7.egg/apscheduler/scheduler.py", line 109, in start
self._real_add_job(job, jobstore, False)
File "/usr/lib/python2.7/site-packages/APScheduler-2.1.0-py2.7.egg/apscheduler/scheduler.py", line 259, in _real_add_job
store.add_job(job)
File "/usr/lib/python2.7/site-packages/APScheduler-2.1.0-py2.7.egg/apscheduler/jobstores/sqlalchemy_store.py", line 58, in add_job
job_dict = job.__getstate__()
File "/usr/lib/python2.7/site-packages/APScheduler-2.1.0-py2.7.egg/apscheduler/job.py", line 120, in __getstate__
state['func_ref'] = obj_to_ref(self.func)
File "/usr/lib/python2.7/site-packages/APScheduler-2.1.0-py2.7.egg/apscheduler/util.py", line 174, in obj_to_ref
raise ValueError('Cannot determine the reference to %s' % repr(obj))
ValueError: Cannot determine the reference to <bound method Test.start of <__main__.Test instance at 0xa119a6c>>
追加したデバッグapscheduler/util.py
は次のとおりです。
161 def obj_to_ref(obj):
162 """
163 Returns the path to the given object.
164 """
165 ref = '%s:%s' % (obj.__module__, get_callable_name(obj))
166 print 'obj_to_ref : obj : %s' % obj
167 print 'obj_to_ref : ref : %s' % ref
168 try:
169 obj2 = ref_to_obj(ref)
170 print 'obj_to_ref : obj2 : %s' % obj2
171 if obj != obj2:
172 raise ValueError
173 except Exception:
174 raise ValueError('Cannot determine the reference to %s' % repr(obj))
175
176 return ref
以下は、次のデバッグ出力ですTest::start()
。
obj_to_ref : obj : <bound method Test.start of <__main__.Test instance at 0xa119a6c>>
obj_to_ref : ref : __main__:Test.start
obj_to_ref : obj2 : <unbound method Test.start>
を(fe )ではなく(fe )に変更scheduler.add_date_job()
するfunction
func
method
Test::start()
self.scheduler.add_date_job(func, alarm_time)
以下は、次のデバッグ出力ですfunc()
。
obj_to_ref : obj : <function func at 0xb768ed14>
obj_to_ref : ref : __main__:func
obj_to_ref : obj2 : <function func at 0xb768ed14>
私はここで何か間違ったことをしていますか?apscheduler/util.py
または、これは関数のバグSQLAlchemyJobStore
ですか?
既知の回避策はありますか?!