Skip to content

Commit

Permalink
feat: make backoff_max configurable with default of 120
Browse files Browse the repository at this point in the history
  • Loading branch information
barrett-schonefeld committed Aug 27, 2021
1 parent 3f19538 commit 434d06c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
10 changes: 6 additions & 4 deletions src/urllib3/util/retry.py
Expand Up @@ -153,7 +153,7 @@ class Retry:
seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
than :attr:`Retry.BACKOFF_MAX`.
than :attr:`Retry.backoff_max`.
By default, backoff is disabled (set to 0).
Expand Down Expand Up @@ -191,8 +191,8 @@ class Retry:
#: Default headers to be used for ``remove_headers_on_redirect``
DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"])

#: Maximum backoff time.
BACKOFF_MAX = 120
#: Default maximum backoff time.
DEFAULT_BACKOFF_MAX = 120

# Backward compatibility; assigned outside of the class.
DEFAULT: ClassVar["Retry"]
Expand All @@ -208,6 +208,7 @@ def __init__(
allowed_methods: Optional[Collection[str]] = DEFAULT_ALLOWED_METHODS,
status_forcelist: Optional[Collection[int]] = None,
backoff_factor: float = 0,
backoff_max: float = self.DEFAULT_BACKOFF_MAX,
raise_on_redirect: bool = True,
raise_on_status: bool = True,
history: Optional[Tuple[RequestHistory, ...]] = None,
Expand All @@ -230,6 +231,7 @@ def __init__(
self.status_forcelist = status_forcelist or set()
self.allowed_methods = allowed_methods
self.backoff_factor = backoff_factor
self.backoff_max = backoff_max
self.raise_on_redirect = raise_on_redirect
self.raise_on_status = raise_on_status
self.history = history or ()
Expand Down Expand Up @@ -293,7 +295,7 @@ def get_backoff_time(self) -> float:
return 0

backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
return float(min(self.BACKOFF_MAX, backoff_value))
return float(min(self.backoff_max, backoff_value))

def parse_retry_after(self, retry_after: str) -> float:
seconds: float
Expand Down
23 changes: 22 additions & 1 deletion test/test_retry.py
Expand Up @@ -131,7 +131,7 @@ def test_status_counter(self) -> None:

def test_backoff(self) -> None:
""" Backoff is computed correctly """
max_backoff = Retry.BACKOFF_MAX
max_backoff = Retry.DEFAULT_BACKOFF_MAX

retry = Retry(total=100, backoff_factor=0.2)
assert retry.get_backoff_time() == 0 # First request
Expand All @@ -155,6 +155,27 @@ def test_backoff(self) -> None:

assert retry.get_backoff_time() == max_backoff

def test_configurable_backoff_max(self) -> None:
""" Configurable backoff is computed correctly """
max_backoff = 1

retry = Retry(total=100, backoff_factor=0.2, backoff_max=max_backoff)
assert retry.get_backoff_time() == 0 # First request

retry = retry.increment(method="GET")
assert retry.get_backoff_time() == 0 # First retry

retry = retry.increment(method="GET")
assert retry.backoff_factor == 0.2
assert retry.total == 98
assert retry.get_backoff_time() == 0.4 # Start backoff

retry = retry.increment(method="GET")
assert retry.get_backoff_time() == 0.8

retry = retry.increment(method="GET")
assert retry.get_backoff_time() == max_backoff

def test_zero_backoff(self) -> None:
retry = Retry()
assert retry.get_backoff_time() == 0
Expand Down

0 comments on commit 434d06c

Please sign in to comment.