backoff
backoff copied to clipboard
Minimum delay
Is there a way to specify a minimum delay? For example, we want the first retry to be at 15 seconds and then increase the delay per the formula?
a = minimum + factor * base ** n
If not, any issue if we add one? I can submit a PR.
I was looking for how to change the initial delay, and it took a bit to figure out that factor
and/or base
as they are exposed, so it is possible to change them, at least for the exponential backoff. There is no example on how to do it in README.md, so I thought I'd post a short one in this thread. It is not exactly what this thread is asking for, but it gives some level of control over the initial delay.
backoff_example.py
:
import backoff
def backoff_handler(details):
print(
"Backing off {wait:0.1f} seconds after {tries} tries "
"calling function {target} with args {args} and kwargs "
"{kwargs}".format(**details)
)
@backoff.on_exception(
backoff.expo,
Exception,
max_tries=5,
on_backoff=backoff_handler,
jitter=None,
factor=2,
)
def myfunc():
print("called myfunc")
raise Exception("myfunc failed")
if __name__ == "__main__":
myfunc()
$ python backoff_example.py
called myfunc
Backing off 2.0 seconds after 1 tries calling function <function myfunc at 0x10da554d0> with args () and kwargs {}
called myfunc
Backing off 4.0 seconds after 2 tries calling function <function myfunc at 0x10da554d0> with args () and kwargs {}
called myfunc
Backing off 8.0 seconds after 3 tries calling function <function myfunc at 0x10da554d0> with args () and kwargs {}
called myfunc
Backing off 16.0 seconds after 4 tries calling function <function myfunc at 0x10da554d0> with args () and kwargs {}
called myfunc
Traceback (most recent call last):
File "backoff_example.py", line 26, in <module>
myfunc()
File "/Users/sryabkov/.asdf/installs/python/3.7.13/lib/python3.7/site-packages/backoff/_sync.py", line 105, in retry
ret = target(*args, **kwargs)
File "backoff_example.py", line 22, in myfunc
raise Exception("myfunc failed")
Exception: myfunc failed
For anyone coming to this issue as I did, this is the approach I took for this:
def _min_expo_wait(min_wait: float):
"""Exponential backoff with a minimum wait time."""
def f(*args, **kwargs):
yield max(min_wait, next(backoff.expo(*args, **kwargs), min_wait))
return f
@backoff.on_exception(
_min_expo_wait(60.0),
some.Exception,
max_tries=3,
)
The original proposed formula do not match with my expectation of exponential wait with a minimum, the code below will follow this one instead:
a = max(minimum, factor * base ** n)