我正在尝试在串行查询上实现retry decorator。我的代码的总体思路如下所示。当装饰器是层次结构中的一种方法时,我正在努力使其重试。如果该方法是引发异常的方法中的一种,该如何重试该方法?
一个令人沮丧的并发症是每次重试的增量时间取决于实际命令。一些命令比其他命令需要更多时间。这就是为什么我传入了extra_time_per_retry,并且无法使用传统的@retry样式实现重试装饰器的原因。
仅供参考,_serial是通过pySerial在 init 上的类中创建的。
我让它与引发异常的方法正上方的重试装饰器一起使用。我希望上面两个可以保持我的代码干净。
我尝试为重试装饰器提供确切的异常类型,但是无法正常工作。
def _query_with_retries(self, cmd, extra_time_per_retry):
_retriable_query = retry(stop_max_attempt_number=5,
wait_incrementing_start=self._serial.timeout + extra_time_per_retry,
wait_incrementing_increment=10)(self._query)
return _retriable_query(cmd)
def _query(self, cmd):
cmd_msg = cmd + '\r'
self._serial.reset_input_buffer()
self._serial.reset_output_buffer()
self._serial.write(cmd_msg)
return self._readlines()
def _readlines(self):
response_str = self._serial.read_until('\r', 256) # Max 256 bytes
# Parse response here, if a bad one set bad_response = true
if bad_response:
raise ResponseError("Response had custom error xyz")
答案 0 :(得分:1)
我想您可以将对_readlines()
的调用打包到一个异常处理块中,从而引发错误:
python 3.x
@retry
def _query(self, cmd):
cmd_msg = cmd + '\r'
self._serial.reset_input_buffer()
self._serial.reset_output_buffer()
self._serial.write(cmd_msg)
try:
answer = self._readlines()
except Exception as e:
raise e
return answer
python 2.x
@retry
def _query(self, cmd):
cmd_msg = cmd + '\r'
self._serial.reset_input_buffer()
self._serial.reset_output_buffer()
self._serial.write(cmd_msg)
try:
answer = self._readlines()
except Exception:
t, v, tb = sys.exc_info()
raise t, v, tb
return answer
这样,您可以在发生异常时直接捕获异常,并将其引发到将重试的方法中。我不确定这对您是否足够整理,但是应该可以。
有些人可能会抱怨使用空白的except Exception
,但是由于我总是立即加注,因此看不到任何危害。