Python APSCheduler 异常管理
Python APSCheduler Exception management
我在脚本中使用模块 APScheduler
,我使用 BlockingScheduler
。我有一些定期工作。如果这个工作 raise
一个 Exception
,无论我 expect
它在 try
还是让它传播,我的线程都不会 return。然后我到达 max_instance
并且不再执行任何作业。
使用 BlockingScheduler
时,我应该如何在线程中管理 Execptions
?
这里我的 MWE 说明了我的问题:
from apscheduler.schedulers.blocking import BlockingScheduler
import threading
class x:
def __init__(self):
self._lock = threading.Lock()
def __enter__(self):
print("ENTER")
self._lock.acquire()
print("LOCK")
raise Exception("ERROR")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("EXIT")
self._lock.release()
print("UNLOCK")
a = x()
def test():
print("TEST")
with a:
print("WITH")
pollingScheduler = BlockingScheduler()
pollingScheduler.add_job(test, 'interval', seconds=1, max_instances=1)
pollingScheduler.start()
我预计在引发异常时必须调用 __exit__()
方法,即使引发异常的是 __enter__()
。睾丸后,我看到 __exit__()
不是这样的场景。因此它会导致死锁和线程卡住。
我该如何解决?
看起来 __enter__()
不能引发异常。对吗?
这里的问题是 __exit__
只有在 __enter__
成功完成时才会被调用。由于您在 __enter__
中引发异常,因此锁处于已获取状态,因此作业的后续 运行 将在尝试获取锁时挂起。如果您期望 __enter__
中出现异常,请将其包装在 try...except
块中,如果引发异常,该块将释放锁。
我在脚本中使用模块 APScheduler
,我使用 BlockingScheduler
。我有一些定期工作。如果这个工作 raise
一个 Exception
,无论我 expect
它在 try
还是让它传播,我的线程都不会 return。然后我到达 max_instance
并且不再执行任何作业。
使用 BlockingScheduler
时,我应该如何在线程中管理 Execptions
?
这里我的 MWE 说明了我的问题:
from apscheduler.schedulers.blocking import BlockingScheduler
import threading
class x:
def __init__(self):
self._lock = threading.Lock()
def __enter__(self):
print("ENTER")
self._lock.acquire()
print("LOCK")
raise Exception("ERROR")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("EXIT")
self._lock.release()
print("UNLOCK")
a = x()
def test():
print("TEST")
with a:
print("WITH")
pollingScheduler = BlockingScheduler()
pollingScheduler.add_job(test, 'interval', seconds=1, max_instances=1)
pollingScheduler.start()
我预计在引发异常时必须调用 __exit__()
方法,即使引发异常的是 __enter__()
。睾丸后,我看到 __exit__()
不是这样的场景。因此它会导致死锁和线程卡住。
我该如何解决?
看起来 __enter__()
不能引发异常。对吗?
这里的问题是 __exit__
只有在 __enter__
成功完成时才会被调用。由于您在 __enter__
中引发异常,因此锁处于已获取状态,因此作业的后续 运行 将在尝试获取锁时挂起。如果您期望 __enter__
中出现异常,请将其包装在 try...except
块中,如果引发异常,该块将释放锁。