backoff icon indicating copy to clipboard operation
backoff copied to clipboard

Minimum delay

Open alandtse opened this issue 4 years ago • 2 comments

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.

alandtse avatar Feb 10 '20 03:02 alandtse

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

sryabkov avatar Dec 24 '22 04:12 sryabkov

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)

photonbit avatar Mar 05 '24 10:03 photonbit