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(giveup_hdlrs, *details) raise seconds = _next_wait(wait, jitter, elapsed, max_time_) _call_handlers(backoff_hdlrs, *details, wait=seconds) time.sleep(seconds) else: _call_handlers(success_hdlrs, *details) return ret
async 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) got_one_item = False try: async for item in target(*args, **kwargs): got_one_item = True yield item except exception as e: # If we've already fed a result out of this method, # we can't pull it back. So don't try to pull back/retry # the exception either. if got_one_item: raise giveup_result = await giveup(e) max_tries_exceeded = (tries == max_tries_) max_time_exceeded = (max_time_ is not None and elapsed >= max_time_) if giveup_result or max_tries_exceeded or max_time_exceeded: await _call_handlers(on_giveup, *details) raise try: seconds = _next_wait(wait, jitter, elapsed, max_time_) except StopIteration: # pragma: no cover await _call_handlers(on_giveup, *details) raise e await _call_handlers(on_backoff, *details, wait=seconds) # Note: there is no convenient way to pass explicit event # loop to decorator, so here we assume that either default # thread event loop is set and correct (it mostly is # by default), or Python >= 3.5.3 or Python >= 3.6 is used # where loop.get_event_loop() in coroutine guaranteed to # return correct value. # See for details: # <https://groups.google.com/forum/#!topic/python-tulip/yF9C-rFpiKk> # <https://bugs.python.org/issue28613> await asyncio.sleep(seconds) else: await _call_handlers(on_success, *details) return
async 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 = await 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: await _call_handlers(on_giveup, *details, value=ret) break try: seconds = _next_wait(wait, jitter, elapsed, max_time_) except StopIteration: await _call_handlers(on_giveup, *details, value=ret) break await _call_handlers(on_backoff, *details, value=ret, wait=seconds) # Note: there is no convenient way to pass explicit event # loop to decorator, so here we assume that either default # thread event loop is set and correct (it mostly is # by default), or Python >= 3.5.3 or Python >= 3.6 is used # where loop.get_event_loop() in coroutine guaranteed to # return correct value. # See for details: # <https://groups.google.com/forum/#!topic/python-tulip/yF9C-rFpiKk> # <https://bugs.python.org/issue28613> await asyncio.sleep(seconds) continue else: await _call_handlers(on_success, *details, value=ret) break return ret
async 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 = await 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: await _call_handlers(on_giveup, *details, value=ret) break try: seconds = _next_wait(wait, jitter, elapsed, max_time_) except StopIteration: await _call_handlers(on_giveup, *details, value=ret) break await _call_handlers(on_backoff, *details, value=ret, wait=seconds) # Note: there is no convenient way to pass explicit event # loop to decorator, so here we assume that either default # thread event loop is set and correct (it mostly is # by default), or Python >= 3.5.3 or Python >= 3.6 is used # where loop.get_event_loop() in coroutine guaranteed to # return correct value. # See for details: # <https://groups.google.com/forum/#!topic/python-tulip/yF9C-rFpiKk> # <https://bugs.python.org/issue28613> await asyncio.sleep(seconds) continue else: await _call_handlers(on_success, *details, value=ret) break return ret
def retry(*args, **kwargs): # change names because python 2.x doesn't have nonlocal max_tries_ = _maybe_call(max_tries) tries = 0 wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 details = (target, args, kwargs, tries) try: ret = target(*args, **kwargs) except exception as e: if giveup(e) or tries == max_tries_: _call_handlers(giveup_hdlrs, *details) raise seconds = _next_wait(wait, jitter) _call_handlers(backoff_hdlrs, *details, wait=seconds) time.sleep(seconds) else: _call_handlers(success_hdlrs, *details) return ret
def retry(*args, **kwargs): # change names because python 2.x doesn't have nonlocal max_tries_ = _maybe_call(max_tries) tries = 0 wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 details = (target, args, kwargs, tries) ret = target(*args, **kwargs) if predicate(ret): if tries == max_tries_: _call_handlers(giveup_hdlrs, *details, value=ret) break seconds = _next_wait(wait, jitter) _call_handlers(backoff_hdlrs, *details, value=ret, wait=seconds) time.sleep(seconds) continue else: _call_handlers(success_hdlrs, *details, value=ret) break return ret
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 = _total_seconds(datetime.datetime.now() - start) details = (target, args, kwargs, tries, elapsed) try: ret = yield from target(*args, **kwargs) except exception as e: giveup_result = yield from giveup(e) max_tries_exceeded = (tries == max_tries_) max_time_exceeded = (max_time_ is not None and elapsed >= max_time_) if giveup_result or max_tries_exceeded or max_time_exceeded: yield from _call_handlers(giveup_hdlrs, *details) raise seconds = _next_wait(wait, jitter, elapsed, max_time_) yield from _call_handlers(backoff_hdlrs, *details, wait=seconds) # Note: there is no convenient way to pass explicit event # loop to decorator, so here we assume that either default # thread event loop is set and correct (it mostly is # by default), or Python >= 3.5.3 or Python >= 3.6 is used # where loop.get_event_loop() in coroutine guaranteed to # return correct value. # See for details: # <https://groups.google.com/forum/#!topic/python-tulip/yF9C-rFpiKk> # <https://bugs.python.org/issue28613> yield from asyncio.sleep(seconds) else: yield from _call_handlers(success_hdlrs, *details) return ret
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
def retry(*args, **kwargs): # change names because python 2.x doesn't have nonlocal max_tries_ = _maybe_call(max_tries) tries = 0 wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 details = (target, args, kwargs, tries) ret = yield from target(*args, **kwargs) if predicate(ret): if tries == max_tries_: yield from _call_handlers(giveup_hdlrs, *details, value=ret) break seconds = _next_wait(wait, jitter) yield from _call_handlers(backoff_hdlrs, *details, value=ret, wait=seconds) # Note: there is no convenient way to pass explicit event # loop to decorator, so here we assume that either default # thread event loop is set and correct (it mostly is # by default), or Python >= 3.5.3 or Python >= 3.6 is used # where loop.get_event_loop() in coroutine guaranteed to # return correct value. # See for details: # <https://groups.google.com/forum/#!topic/python-tulip/yF9C-rFpiKk> # <https://bugs.python.org/issue28613> yield from asyncio.sleep(seconds) continue else: yield from _call_handlers(success_hdlrs, *details, value=ret) break return ret