diff --git a/backoff/_async.py b/backoff/_async.py index 82fd477..18af09f 100644 --- a/backoff/_async.py +++ b/backoff/_async.py @@ -1,8 +1,7 @@ # coding:utf-8 -import datetime +import time import functools import asyncio -from datetime import timedelta from backoff._common import (_init_wait_gen, _maybe_call, _next_wait) @@ -41,6 +40,8 @@ def retry_predicate(target, wait_gen, predicate, *, max_tries, max_time, jitter, on_success, on_backoff, on_giveup, + monotonic_time=None, + sleep=None, wait_gen_kwargs): on_success = _ensure_coroutines(on_success) on_backoff = _ensure_coroutines(on_backoff) @@ -60,11 +61,11 @@ async def retry(*args, **kwargs): max_time_value = _maybe_call(max_time) tries = 0 - start = datetime.datetime.now() + start = (monotonic_time or time.monotonic)() wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 - elapsed = timedelta.total_seconds(datetime.datetime.now() - start) + elapsed = (monotonic_time or time.monotonic)() - start details = { "target": target, "args": args, @@ -102,7 +103,7 @@ async def retry(*args, **kwargs): # See for details: # # - await asyncio.sleep(seconds) + await (sleep or asyncio.sleep)(seconds) continue else: await _call_handlers(on_success, **details, value=ret) @@ -117,6 +118,7 @@ def retry_exception(target, wait_gen, exception, *, max_tries, max_time, jitter, giveup, on_success, on_backoff, on_giveup, raise_on_giveup, + sleep=None, monotonic_time=None, wait_gen_kwargs): on_success = _ensure_coroutines(on_success) on_backoff = _ensure_coroutines(on_backoff) @@ -134,11 +136,11 @@ async def retry(*args, **kwargs): max_time_value = _maybe_call(max_time) tries = 0 - start = datetime.datetime.now() + start = (monotonic_time or time.monotonic)() wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 - elapsed = timedelta.total_seconds(datetime.datetime.now() - start) + elapsed = (monotonic_time or time.monotonic)() - start details = { "target": target, "args": args, @@ -180,7 +182,7 @@ async def retry(*args, **kwargs): # See for details: # # - await asyncio.sleep(seconds) + await (sleep or asyncio.sleep)(seconds) else: await _call_handlers(on_success, **details) diff --git a/backoff/_decorator.py b/backoff/_decorator.py index 77ed8c2..d4fe6fe 100644 --- a/backoff/_decorator.py +++ b/backoff/_decorator.py @@ -33,6 +33,8 @@ def on_predicate(wait_gen: _WaitGenerator, on_success: Union[_Handler, Iterable[_Handler], None] = None, on_backoff: Union[_Handler, Iterable[_Handler], None] = None, on_giveup: Union[_Handler, Iterable[_Handler], None] = None, + monotonic_time: Optional[Callable[[], float]] = None, + sleep: Optional[Callable[[float], None]] = None, logger: _MaybeLogger = 'backoff', backoff_log_level: int = logging.INFO, giveup_log_level: int = logging.ERROR, @@ -113,6 +115,8 @@ def decorate(target): on_success=on_success, on_backoff=on_backoff, on_giveup=on_giveup, + monotonic_time=monotonic_time, + sleep=sleep, wait_gen_kwargs=wait_gen_kwargs ) diff --git a/backoff/_sync.py b/backoff/_sync.py index 4371e16..6edef86 100644 --- a/backoff/_sync.py +++ b/backoff/_sync.py @@ -1,8 +1,6 @@ # coding:utf-8 -import datetime import functools import time -from datetime import timedelta from backoff._common import (_init_wait_gen, _maybe_call, _next_wait) @@ -24,6 +22,8 @@ def retry_predicate(target, wait_gen, predicate, *, max_tries, max_time, jitter, on_success, on_backoff, on_giveup, + monotonic_time=None, + sleep=None, wait_gen_kwargs): @functools.wraps(target) @@ -32,11 +32,11 @@ def retry(*args, **kwargs): max_time_value = _maybe_call(max_time) tries = 0 - start = datetime.datetime.now() + start = (monotonic_time or time.monotonic)() wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 - elapsed = timedelta.total_seconds(datetime.datetime.now() - start) + elapsed = (monotonic_time or time.monotonic)() - start details = { "target": target, "args": args, @@ -65,7 +65,7 @@ def retry(*args, **kwargs): _call_handlers(on_backoff, **details, value=ret, wait=seconds) - time.sleep(seconds) + (sleep or time.sleep)(seconds) continue else: _call_handlers(on_success, **details, value=ret) @@ -80,6 +80,7 @@ def retry_exception(target, wait_gen, exception, *, max_tries, max_time, jitter, giveup, on_success, on_backoff, on_giveup, raise_on_giveup, + monotonic_time=None, wait_gen_kwargs): @functools.wraps(target) @@ -88,11 +89,11 @@ def retry(*args, **kwargs): max_time_value = _maybe_call(max_time) tries = 0 - start = datetime.datetime.now() + start = (monotonic_time or time.monotonic)() wait = _init_wait_gen(wait_gen, wait_gen_kwargs) while True: tries += 1 - elapsed = timedelta.total_seconds(datetime.datetime.now() - start) + elapsed = (monotonic_time or time.monotonic)() - start details = { "target": target, "args": args, @@ -124,7 +125,7 @@ def retry(*args, **kwargs): _call_handlers(on_backoff, **details, wait=seconds, exception=e) - time.sleep(seconds) + (sleep or time.sleep)(seconds) else: _call_handlers(on_success, **details)