Skip to content

fix(hoverclient): retry-with-backoff on HTTP 429/503 (rate-limit) — v0.5.3#35

Merged
intel352 merged 1 commit into
mainfrom
fix/hover-429-backoff
Jun 2, 2026
Merged

fix(hoverclient): retry-with-backoff on HTTP 429/503 (rate-limit) — v0.5.3#35
intel352 merged 1 commit into
mainfrom
fix/hover-429-backoff

Conversation

@intel352
Copy link
Copy Markdown
Contributor

@intel352 intel352 commented Jun 2, 2026

The DNS catalog delegation import does ~30 per-domain GetDomainDelegation reads 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: honors Retry-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

…0.5.3

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 2, 2026 16:54
@intel352 intel352 merged commit 499163d into main Jun 2, 2026
5 checks passed
@intel352 intel352 deleted the fix/hover-429-backoff branch June 2, 2026 16:57
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 using Retry-After when 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 thread pkg/hoverclient/client.go
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 thread pkg/hoverclient/client.go
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 }()

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.

2 participants