Commit 1b429e2a authored by Iustin Pop's avatar Iustin Pop
Browse files

Fix utils.WaitForFdCondition inner retry loop

Commit dfdc4060

 added WaitForFdCondition which uses utils.Retry without
handling timeout exceptions. This breaks any nested retry loops.

This patch fixes the above function, and also changes utils.Retry to
detect and warn future similar cases. In addition, we add a few small
unittests for utils.Retry.
Signed-off-by: default avatarIustin Pop <>
Reviewed-by: default avatarMichael Hanselmann <>
parent cc2f004d
......@@ -166,7 +166,8 @@ class AsyncUDPSocket(asyncore.dispatcher):
@return: True if some data has been handled, False otherwise
if utils.WaitForFdCondition(self, select.POLLIN, timeout) & select.POLLIN:
result = utils.WaitForFdCondition(self, select.POLLIN, timeout)
if result is not None and result & select.POLLIN:
return True
......@@ -1579,8 +1579,11 @@ def WaitForFdCondition(fdobj, event, timeout):
if timeout is not None:
retrywaiter = FdConditionWaiterHelper(timeout)
result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout,
args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout)
result = Retry(retrywaiter.Poll, RETRY_REMAINING_TIME, timeout,
args=(fdobj, event), wait_fn=retrywaiter.UpdateTimeout)
except RetryTimeout:
result = None
result = None
while result is None:
......@@ -2606,6 +2609,9 @@ def Retry(fn, delay, timeout, args=None, wait_fn=time.sleep,
return fn(*args)
except RetryAgain:
except RetryTimeout:
raise errors.ProgrammerError("Nested retry loop detected that didn't"
" handle RetryTimeout")
remaining_time = end_time - _time_fn()
......@@ -1535,5 +1535,28 @@ class TestMakedirs(unittest.TestCase):
class TestRetry(testutils.GanetiTestCase):
def _RaiseRetryAgain():
raise utils.RetryAgain()
def _WrongNestedLoop(self):
return utils.Retry(self._RaiseRetryAgain, 0.01, 0.02)
def testRaiseTimeout(self):
self.failUnlessRaises(utils.RetryTimeout, utils.Retry,
self._RaiseRetryAgain, 0.01, 0.02)
def testComplete(self):
self.failUnlessEqual(utils.Retry(lambda: True, 0, 1), True)
def testNestedLoop(self):
self.failUnlessRaises(errors.ProgrammerError, utils.Retry,
self._WrongNestedLoop, 0, 1)
except utils.RetryTimeout:"Didn't detect inner loop's exception")
if __name__ == '__main__':
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment