Conversation
Code ReviewOverall this is a solid, well-structured addition. The implementation is clean and the test coverage is good. A few observations: Bug: Unnecessary sleep on final retry attemptIn # current behaviour – sleeps even when we are about to give up
for attempt in range(RETRY_MAX_ATTEMPTS):
...
if r.status_code == httpx.codes.TOO_MANY_REQUESTS:
delay = self._get_retry_delay(r, attempt)
await asyncio.sleep(delay) # pointless on the last iteration
continue
raise AqualinkServiceThrottledException(...)One idiomatic fix: for attempt in range(RETRY_MAX_ATTEMPTS):
...
if r.status_code == httpx.codes.TOO_MANY_REQUESTS:
if attempt < RETRY_MAX_ATTEMPTS - 1:
delay = self._get_retry_delay(r, attempt)
LOGGER.warning(...)
await asyncio.sleep(delay)
continue
raise AqualinkServiceThrottledException(...)The test Minor:
|
Retry with exponential backoff when the server returns 429 Too Many Requests. Addresses throttling when multiple systems are polled concurrently. - add AqualinkServiceThrottledException raised when retries exhausted - add retry constants (RETRY_MAX_ATTEMPTS, RETRY_BASE_DELAY, RETRY_MAX_DELAY) - retry loop in send_request() with Retry-After header support and exponential backoff with jitter; only 429 is retried - log all 429 response headers at DEBUG for rate-limit header discovery - fix mutation of module-level AQUALINK_HTTP_HEADERS dict - add unit tests for retry, Retry-After, exhaustion, and non-retry codes
Retry with exponential backoff when the server returns 429 Too Many
Requests. Addresses throttling when multiple systems are polled
concurrently.
exponential backoff with jitter; only 429 is retried