Skip to content

Commit f306073

Browse files
authored
feat: use exponential backoff when retrying requests (#417)
Replace current `retries * retry_interval` backoff with a truncated exponential backoff algorithm.
1 parent 3a83ed7 commit f306073

2 files changed

Lines changed: 7 additions & 4 deletions

File tree

hcloud/_client.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ class Client:
8383
_version = __version__
8484
__user_agent_prefix = "hcloud-python"
8585

86-
_retry_interval = 0.5
86+
_retry_interval = exponential_backoff_function(
87+
base=1.0, multiplier=2, cap=60.0, jitter=True
88+
)
8789
_retry_max_retries = 5
8890

8991
def __init__(
@@ -289,7 +291,8 @@ def request( # type: ignore[no-untyped-def]
289291
error["code"] == "rate_limit_exceeded"
290292
and retries < self._retry_max_retries
291293
):
292-
time.sleep(retries * self._retry_interval)
294+
# pylint: disable=too-many-function-args
295+
time.sleep(self._retry_interval(retries))
293296
retries += 1
294297
continue
295298

tests/unit/test_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ def test_request_500_empty_content(self, client, fail_response):
185185
assert str(error) == "Internal Server Error (500)"
186186

187187
def test_request_limit(self, client, rate_limit_response):
188-
client._retry_interval = 0
188+
client._retry_interval = constant_backoff_function(0.0)
189189
client._requests_session.request.return_value = rate_limit_response
190190
with pytest.raises(APIException) as exception_info:
191191
client.request(
@@ -197,7 +197,7 @@ def test_request_limit(self, client, rate_limit_response):
197197
assert error.message == "limit of 10 requests per hour reached"
198198

199199
def test_request_limit_then_success(self, client, rate_limit_response):
200-
client._retry_interval = 0
200+
client._retry_interval = constant_backoff_function(0.0)
201201
response = requests.Response()
202202
response.status_code = 200
203203
response._content = json.dumps({"result": "data"}).encode("utf-8")

0 commit comments

Comments
 (0)