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 块中,如果引发异常,该块将释放锁。