fix(hoverclient): retry-with-backoff on HTTP 429/503 (rate-limit) — v0.5.3#35
Merged
Conversation
…0.5.3 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a centralized, context-aware HTTP retry-with-backoff helper to the Hover HTTP backend to mitigate rate limiting (HTTP 429/503) during bursty read paths, and bumps the plugin version to v0.5.3.
Changes:
- Introduces
(*Client).do()to retry GET/read requests on 429/503 usingRetry-Afterwhen present, otherwise exponential backoff with jitter. - Routes key GET endpoints (
ListDomains, record/domain reads, delegation reads, CSRF fetch) through the new retry helper. - Adds unit tests validating retry success and retry exhaustion behavior; bumps plugin.json version to 0.5.3.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| plugin.json | Bumps plugin version to 0.5.3. |
| cmd/workflow-plugin-hover/plugin.json | Keeps embedded plugin metadata version in sync with 0.5.3. |
| pkg/hoverclient/client.go | Adds retry helper and applies it to GET/read HTTP calls. |
| pkg/hoverclient/client_test.go | Adds tests covering 429 retry behavior and max-retry failure. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+159
to
+176
| // Compute wait duration. | ||
| wait := retryBaseDelay * time.Duration(math.Pow(2, float64(attempt))) | ||
| if wait > maxBackoffCap { | ||
| wait = maxBackoffCap | ||
| } | ||
| // Honor Retry-After header if present and numeric. | ||
| if ra := resp.Header.Get("Retry-After"); ra != "" { | ||
| if secs, parseErr := strconv.Atoi(ra); parseErr == nil && secs >= 0 { | ||
| wait = time.Duration(secs) * time.Second | ||
| } | ||
| } | ||
| // Add ±10 % jitter to spread concurrent retries. | ||
| // Non-security use: jitter is for load spreading, not randomness quality. | ||
| jitter := time.Duration(float64(wait) * (rand.Float64()*0.2 - 0.1)) //nolint:gosec | ||
| wait += jitter | ||
| if wait < 0 { | ||
| wait = 0 | ||
| } |
Comment on lines
+150
to
+152
| // Drain and close so the connection can be reused. | ||
| _, _ = io.Copy(io.Discard, io.LimitReader(resp.Body, 4096)) | ||
| resp.Body.Close() |
Comment on lines
+770
to
+772
| // Speed up backoff so the test runs fast. | ||
| retryBaseDelay = 1 * time.Millisecond | ||
| defer func() { retryBaseDelay = 1 * time.Second }() |
Comment on lines
+813
to
+816
| // Speed up backoff. | ||
| retryBaseDelay = 1 * time.Millisecond | ||
| defer func() { retryBaseDelay = 1 * time.Second }() | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The DNS catalog delegation import does ~30 per-domain
GetDomainDelegationreads on top of ~30 record reads; Hover (Imperva) rate-limited the burst with HTTP 429 → delegation import failed (run 26834462237). Adds a central retry helper on the GET-read path: honorsRetry-After, else exponential backoff + jitter, capped 30s, bounded 5 retries, ctx-aware; body-safe (GET-only) so bursts self-throttle. Bumps plugin.json → 0.5.3 (release version sync). go test green.Unblocks the both-layers catalog import. Followed by v0.5.3 release + gocodealone-dns re-pin + re-import.
🤖 Generated with Claude Code