blob: 59cf581e488ca17f85e8e44504ced95816cba2c7 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import logging
import time
from . import utils
log = logging.getLogger(__name__)
def retry(maxRetries, tryFn):
"""
Retry `tryFn` based on `maxRetries`. Each call to `tryFn` will pass a
callable which should be called with the exception object when an exception
can be retried. Exceptions raised from `tryFn` are treated as fatal.
"""
retry = -1 # we plus first in the loop, and attempt 1 is retry 0
while True:
retry += 1
# if this isn't the first retry then we sleep
if retry > 0:
snooze = float(retry * retry) / 10.0
log.info('Sleeping %0.2f seconds for exponential backoff', snooze)
time.sleep(utils.calculateSleepTime(retry))
retriableException = None
def retryFor(exc):
nonlocal retriableException
retriableException = exc
res = tryFn(retryFor)
if not retriableException:
return res
if retry < maxRetries:
log.warning(f'Retrying because of: {retriableException}')
continue
raise retriableException
|