Skip to content

fix: retry transient errors on api autocomplete status GET#115

Open
vtushar06 wants to merge 1 commit into
opencost:mainfrom
vtushar06:harden-api-autocomplete-retry
Open

fix: retry transient errors on api autocomplete status GET#115
vtushar06 wants to merge 1 commit into
opencost:mainfrom
vtushar06:harden-api-autocomplete-retry

Conversation

@vtushar06

Copy link
Copy Markdown
Contributor

Description

Follow-up to #106 (thanks @ameijer for catching that the retries weren't firing). The connection resets in that run were on the OpenCost API client path, not the Prometheus client I hardened in #106.

API.GET already retries transport errors, but GetAutocompleteStatus (used by the autocomplete probe and validation tests) used a raw http.Get that bypassed that retry, so a connection reset there failed the run with no retry and no log, e.g.:

failed to probe /allocation/autocomplete: error getting .../model/allocation/autocomplete?...:
Get "...": read tcp ...: read: connection reset by peer

This routes that GET through a small httpGetWithRetry helper that retries transient transport errors with the same MAX_RETRIES and backoff as API.GET, and logs each retry so they show up in the run output. As a bonus it now uses the shared client's timeout instead of the bare http.Get.

Related

Follow-up to #106.

Testing

  • Added pkg/api/retry_test.go (deterministic, injected RoundTripper): retries transient errors then succeeds, and returns the error after MAX_RETRIES.
  • go build ./..., go vet ./pkg/api/, and the pkg/api tests pass locally.

One thing out of scope: the other failure in that run (TestAllocationAutocompletePrometheusGroundTruth, 74.2% coverage) is a data-coverage assertion, not a network issue, so it's not addressed here.

cc @ameijer

Signed-off-by: Tushar Verma <tusharmyself06@gmail.com>
Copilot AI review requested due to automatic review settings July 1, 2026 12:46
@vtushar06 vtushar06 requested a review from a team as a code owner July 1, 2026 12:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens the OpenCost API client path used by the autocomplete probe/validation by ensuring /allocation/.../autocomplete status GETs go through the same retry-capable HTTP client path as other API calls, and adds deterministic unit coverage for the retry behavior.

Changes:

  • Route GetAutocompleteStatus through a new httpGetWithRetry helper instead of http.Get.
  • Add httpGetWithRetry to retry GET transport errors with the existing MAX_RETRIES and a configurable backoff (test-shortenable).
  • Add deterministic unit tests for retry success and retry exhaustion via an injected RoundTripper.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
pkg/api/api.go Adds httpGetWithRetry and a configurable retry backoff used by the autocomplete status path.
pkg/api/autocomplete.go Switches GetAutocompleteStatus from raw http.Get to the retrying helper using sharedHTTPClient.
pkg/api/retry_test.go Adds deterministic unit tests covering retry success and retry exhaustion for httpGetWithRetry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/api/api.go
Comment on lines +127 to +145
// httpGetWithRetry performs an HTTP GET, retrying transient transport errors
// (such as "connection reset by peer" from the shared demo backend) that
// otherwise fail integration runs spuriously. Each retry is logged so it is
// visible in the run output. These GETs are idempotent, so retrying is safe.
func httpGetWithRetry(client *http.Client, url string) (*http.Response, error) {
var lastErr error
for try := 0; try < MAX_RETRIES; try++ {
resp, err := client.Get(url)
if err == nil {
return resp, nil
}
lastErr = err
if try < MAX_RETRIES-1 {
log.Warnf("error getting %s: %v, retrying... (%d/%d)", url, err, try+1, MAX_RETRIES)
time.Sleep(httpGetRetryBackoff)
}
}
return nil, lastErr
}
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.

3 participants