在下面的代码中,我试图创建一个类'TimedExecutor',如果超过一定的时间限制,它将停止执行传递给其方法'execute'的函数(bar)。但是,即使显示错误消息,程序执行也不会停止。
注意:我们不得对bar()
函数进行任何更改,因为它是由外部模块提供的。
import signal
import time
class MyError(Exception):
"""Base error"""
class MyInheritedError(MyError):
"""Class to inherit from base error"""
class TimeoutListener(object):
def __init__(self, timeout_seconds, error_message="Timeout executing."):
self.timeout_seconds = timeout_seconds
self.error_message = error_message
self.alarm = None
def __enter__(self):
signal.signal(signal.SIGALRM, self._handle_timeout)
signal.alarm(self.timeout_seconds)
def __exit__(self, listener_type, value, traceback):
# Disable the alarm.
if self.alarm:
self.alarm = None
else:
signal.alarm(0)
def _handle_timeout(self, signum, frame):
print("Got the signum %s with frame: %s" % (signum, frame))
raise MyInheritedError(self.error_message + "aditya")
class TimedExecutor(object):
@staticmethod
def execute(timeout_secs, functor, *args, **kwargs):
msg = "Timeout executing method - %s." % functor.__name__
timeout_signal = TimeoutListener(timeout_secs, error_message=msg)
try:
with timeout_signal:
output = functor(*args, **kwargs)
except MyInheritedError as ex:
print("%s did not complete in %s: %s."
% (functor.__name__, timeout_secs, repr(ex)))
raise
return output
def bar():
for _ in range(5):
try:
time.sleep(1)
print("SLEEPING")
except MyInheritedError as ex:
print ex
ob = TimedExecutor.execute(2, bar)
你的算子吞下了你想要致命的例外。
它的一个循环中的bar()
的except子句打印然后丢弃由TimeoutListener
上下文管理器引发的错误。然后循环重新开始。
bar()
应该不会意识到你的TimedExecutor
可能引发的例外情况。相反,bar()
调用.execute()
的调用者应该知道它:
from aditya.utils import TimedExecutor, TimeoutException
...
try:
TimedExecutor.execute(2, bar)
except TimeoutException:
print("Timed out executing bar")