Ensure retry delay respects watch leftover time/timeout

This commit is contained in:
Joshua Harlow 2015-06-18 08:38:55 -07:00
parent a8a7ba63e8
commit dc8745880a
2 changed files with 17 additions and 10 deletions

View File

@ -68,11 +68,12 @@ class Retry(object):
"""A little retry helper object."""
def __init__(self, delay, max_delay,
sleep_func=time.sleep):
sleep_func=time.sleep, watch=None):
self.delay = delay
self.attempts = 0
self.max_delay = max_delay
self.sleep_func = sleep_func
self.watch = watch
def __call__(self, fn, *args, **kwargs):
while True:
@ -86,6 +87,10 @@ class Retry(object):
else:
actual_delay = self.max_delay
actual_delay = max(0.0, actual_delay)
if self.watch is not None:
leftover = self.watch.leftover()
if leftover is not None and leftover < actual_delay:
actual_delay = leftover
self.sleep_func(actual_delay)
@ -97,13 +102,17 @@ class StopWatch(object):
self.started_at = None
self.stopped_at = None
def leftover(self):
if self.duration is None:
return None
return max(0.0, self.duration - self.elapsed())
def elapsed(self):
if self.stopped_at is not None:
t = self.stopped_at
end_time = self.stopped_at
else:
t = now()
e = t - self.started_at
return max(0.0, e)
end_time = now()
return max(0.0, end_time - self.started_at)
def __enter__(self):
self.start()
@ -120,7 +129,4 @@ class StopWatch(object):
if self.duration is None:
return False
else:
e = self.elapsed()
if e > self.duration:
return True
return False
return self.elapsed() > self.duration

View File

@ -146,7 +146,8 @@ class _InterProcessLock(object):
max_delay = delay
self._do_open()
watch = _utils.StopWatch(duration=timeout)
r = _utils.Retry(delay, max_delay, sleep_func=self.sleep_func)
r = _utils.Retry(delay, max_delay,
sleep_func=self.sleep_func, watch=watch)
with watch:
gotten = r(self._try_acquire, blocking, watch)
if not gotten: