Skip to content

Commit 1c4c844

Browse files
committed
Added unit tests for _retry.py
1 parent 4c3a6d9 commit 1c4c844

File tree

2 files changed

+465
-7
lines changed

2 files changed

+465
-7
lines changed

firebase_admin/_retry.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
class HttpxRetry:
3636
"""HTTPX based retry config"""
3737
# TODO: Decide
38-
# urllib3.Retry ignores the status_forcelist and only respects Retry-After header
39-
# for 413, 429 and 503 errors.
38+
# urllib3.Retry ignores the status_forcelist when respecting Retry-After header
39+
# Only 413, 429 and 503 errors are retried with the Retry-After header.
4040
# Should we do the same?
4141
# Default status codes to be used for ``status_forcelist``
4242
RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
@@ -123,32 +123,39 @@ def _parse_retry_after(self, retry_after_header: str) -> float | None:
123123

124124
def get_retry_after(self, response: httpx.Response) -> float | None:
125125
"""Determine the Retry-After time needed before sending the next request."""
126-
retry_after_header = response.headers.get('Retry_After', None)
126+
retry_after_header = response.headers.get('Retry-After', None)
127127
if retry_after_header:
128128
# Convert retry header to a float in seconds
129129
return self._parse_retry_after(retry_after_header)
130130
return None
131131

132132
def get_backoff_time(self):
133133
"""Determine the backoff time needed before sending the next request."""
134-
# request_count is the number of previous request attempts
135-
request_count = len(self.history)
136-
backoff = self.backoff_factor * (2 ** (request_count-1))
134+
# attempt_count is the number of previous request attempts
135+
attempt_count = len(self.history)
136+
# Backoff should be set to 0 until after first retry.
137+
if attempt_count <= 1:
138+
return 0
139+
backoff = self.backoff_factor * (2 ** (attempt_count-1))
137140
if self.backoff_jitter:
138141
backoff += random.random() * self.backoff_jitter
139142
return float(max(0, min(self.backoff_max, backoff)))
140143

141144
async def sleep_for_backoff(self) -> None:
142145
"""Determine and wait the backoff time needed before sending the next request."""
143146
backoff = self.get_backoff_time()
144-
logger.debug('Sleeping for %f seconds following failed request', backoff)
147+
logger.debug('Sleeping for backoff of %f seconds following failed request', backoff)
145148
await asyncio.sleep(backoff)
146149

147150
async def sleep(self, response: httpx.Response) -> None:
148151
"""Determine and wait the time needed before sending the next request."""
149152
if self.respect_retry_after_header:
150153
retry_after = self.get_retry_after(response)
151154
if retry_after:
155+
logger.debug(
156+
'Sleeping for Retry-After header of %f seconds following failed request',
157+
retry_after
158+
)
152159
await asyncio.sleep(retry_after)
153160
return
154161
await self.sleep_for_backoff()

0 commit comments

Comments
 (0)