File size: 3,691 Bytes
0a06673 |
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# coding:utf-8
import datetime
import functools
import time
from datetime import timedelta
from backoff._common import (_init_wait_gen, _maybe_call, _next_wait)
def _call_handlers(hdlrs, target, args, kwargs, tries, elapsed, **extra):
details = {
'target': target,
'args': args,
'kwargs': kwargs,
'tries': tries,
'elapsed': elapsed,
}
details.update(extra)
for hdlr in hdlrs:
hdlr(details)
def retry_predicate(target, wait_gen, predicate,
max_tries, max_time, jitter,
on_success, on_backoff, on_giveup,
wait_gen_kwargs):
@functools.wraps(target)
def retry(*args, **kwargs):
# change names because python 2.x doesn't have nonlocal
max_tries_ = _maybe_call(max_tries)
max_time_ = _maybe_call(max_time)
tries = 0
start = datetime.datetime.now()
wait = _init_wait_gen(wait_gen, wait_gen_kwargs)
while True:
tries += 1
elapsed = timedelta.total_seconds(datetime.datetime.now() - start)
details = (target, args, kwargs, tries, elapsed)
ret = target(*args, **kwargs)
if predicate(ret):
max_tries_exceeded = (tries == max_tries_)
max_time_exceeded = (max_time_ is not None and
elapsed >= max_time_)
if max_tries_exceeded or max_time_exceeded:
_call_handlers(on_giveup, *details, value=ret)
break
try:
seconds = _next_wait(wait, jitter, elapsed, max_time_)
except StopIteration:
_call_handlers(on_giveup, *details)
break
_call_handlers(on_backoff, *details,
value=ret, wait=seconds)
time.sleep(seconds)
continue
else:
_call_handlers(on_success, *details, value=ret)
break
return ret
return retry
def retry_exception(target, wait_gen, exception,
max_tries, max_time, jitter, giveup,
on_success, on_backoff, on_giveup,
wait_gen_kwargs):
@functools.wraps(target)
def retry(*args, **kwargs):
# change names because python 2.x doesn't have nonlocal
max_tries_ = _maybe_call(max_tries)
max_time_ = _maybe_call(max_time)
tries = 0
start = datetime.datetime.now()
wait = _init_wait_gen(wait_gen, wait_gen_kwargs)
while True:
tries += 1
elapsed = timedelta.total_seconds(datetime.datetime.now() - start)
details = (target, args, kwargs, tries, elapsed)
try:
ret = target(*args, **kwargs)
except exception as e:
max_tries_exceeded = (tries == max_tries_)
max_time_exceeded = (max_time_ is not None and
elapsed >= max_time_)
if giveup(e) or max_tries_exceeded or max_time_exceeded:
_call_handlers(on_giveup, *details)
raise
try:
seconds = _next_wait(wait, jitter, elapsed, max_time_)
except StopIteration:
_call_handlers(on_giveup, *details)
raise e
_call_handlers(on_backoff, *details, wait=seconds)
time.sleep(seconds)
else:
_call_handlers(on_success, *details)
return ret
return retry
|