Skip to content

Fix stamina retry pattern so retries actually happen on slow failures - #243

Merged
smnorris merged 2 commits into
mainfrom
issue215
Aug 17, 2026
Merged

Fix stamina retry pattern so retries actually happen on slow failures#243
smnorris merged 2 commits into
mainfrom
issue215

Conversation

@smnorris

Copy link
Copy Markdown
Collaborator

The WFS gateway itself can take up to ~60s to fail with a 504. Since stamina's timeout= is a cumulative deadline across all retries (not per-attempt), the previous timeout=60 was exhausted by a single slow attempt, leaving no budget for any actual retry - matching the reported "retry/stamina not working" symptom.

  • Consolidate _request_count/_request_features/_request_featurecollection's duplicated request+status-handling into one _request() method, with retry-worthiness decided via a stamina on= callable (_is_retryable) instead of which branch happens to call raise_for_status()
  • Retry on 429 (rate limited) in addition to 5xx, and on requests.ConnectionError/Timeout, not just HTTPError
  • Add an HTTP-level timeout to the request itself, so a truly hung connection raises instead of blocking forever
  • Size the retry budget (attempts=5, timeout=300) to fit several real attempts against a service that can be this slow per-attempt
  • Widen _request_schema/_request_capabilities's retry to also catch connection/timeout errors

Tests: added direct unit tests for _is_retryable() covering 5xx, 429, 4xx, and connection/timeout errors. Per stamina's testing docs (https://stamina.hynek.me/en/stable/testing.html), decorator-based retries should rely on stamina.set_active(False) in tests (already in place session-wide here) rather than asserting retry-loop mechanics via set_testing() - that's stamina's job to guarantee, not ours to re-test.

Fixes #215

smnorris and others added 2 commits August 17, 2026 16:28
The WFS gateway itself can take up to ~60s to fail with a 504. Since
stamina's timeout= is a cumulative deadline across all retries (not
per-attempt), the previous timeout=60 was exhausted by a single slow
attempt, leaving no budget for any actual retry - matching the
reported "retry/stamina not working" symptom.

- Consolidate _request_count/_request_features/_request_featurecollection's
  duplicated request+status-handling into one _request() method, with
  retry-worthiness decided via a stamina on= callable (_is_retryable)
  instead of which branch happens to call raise_for_status()
- Retry on 429 (rate limited) in addition to 5xx, and on
  requests.ConnectionError/Timeout, not just HTTPError
- Add an HTTP-level timeout to the request itself, so a truly hung
  connection raises instead of blocking forever
- Size the retry budget (attempts=5, timeout=300) to fit several real
  attempts against a service that can be this slow per-attempt
- Widen _request_schema/_request_capabilities's retry to also catch
  connection/timeout errors

Tests: added direct unit tests for _is_retryable() covering 5xx, 429,
4xx, and connection/timeout errors. Per stamina's testing docs
(https://stamina.hynek.me/en/stable/testing.html), decorator-based
retries should rely on stamina.set_active(False) in tests (already in
place session-wide here) rather than asserting retry-loop mechanics
via set_testing() - that's stamina's job to guarantee, not ours to
re-test.

Fixes #215

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
A 429 was previously logged identically to a generic 5xx service
error, giving no indication the request was actually rate limited
rather than failing. Give 429 its own clear log message, and if the
response carries a Retry-After (standard) or RateLimit-Reset (what
DataBC's Kong gateway sends) header, use that as the exact retry
backoff via stamina's on= hook instead of guessing with the default
exponential backoff.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@smnorris
smnorris merged commit 5643c81 into main Aug 17, 2026
11 checks passed
@smnorris
smnorris deleted the issue215 branch August 17, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

retry/stamina not working properly on timeout?

1 participant