diff --git a/clientutil/backend_test.go b/clientutil/backend_test.go index 561f5be3cb903ee652ab39f2d288e0f8c564c175..6b4e3d8079d7852199546eb49c29a2ed4f221ba6 100644 --- a/clientutil/backend_test.go +++ b/clientutil/backend_test.go @@ -90,7 +90,7 @@ func newErrorHTTPServer(statusCode int) *httpServer { func newJSONHTTPServer() *httpServer { return &httpServer{httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") - io.WriteString(w, "{\"value\": 42}") + io.WriteString(w, "{\"value\": 42}") // nolint }))} } @@ -99,7 +99,7 @@ func newHostCountingJSONHTTPServer() (*httpServer, map[string]int) { return &httpServer{httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { counters[r.Host]++ w.Header().Set("Content-Type", "application/json") - io.WriteString(w, "{\"value\": 42}") + io.WriteString(w, "{\"value\": 42}") // nolint }))}, counters } diff --git a/clientutil/balancer.go b/clientutil/balancer.go index 84633ac271887a35a7575805f8a6633b983949af..d2ca8270fcf27deb3e48e3526a91bb2c8cf004a1 100644 --- a/clientutil/balancer.go +++ b/clientutil/balancer.go @@ -118,30 +118,31 @@ func (b *balancedBackend) Call(ctx context.Context, shard, path string, req, res // Call the backends in the sequence until one succeeds, with an // exponential backoff policy controlled by the outer Context. - var httpResp *http.Response - err = backoff.Retry(func() error { + return backoff.Retry(func() error { req, rerr := b.newJSONRequest(path, shard, data) if rerr != nil { return rerr } innerCtx, cancel := context.WithTimeout(ctx, innerTimeout) - httpResp, rerr = b.do(innerCtx, seq, req) - cancel() - return rerr - }, backoff.WithContext(newExponentialBackOff(), ctx)) - if err != nil { - return err - } - defer httpResp.Body.Close() // nolint + defer cancel() - // Decode the response. - if httpResp.Header.Get("Content-Type") != "application/json" { - return errors.New("not a JSON response") - } - if resp == nil { - return nil - } - return json.NewDecoder(httpResp.Body).Decode(resp) + // When do() returns successfully, we already know that the + // response had an HTTP status of 200. + httpResp, rerr := b.do(innerCtx, seq, req) + if rerr != nil { + return rerr + } + defer httpResp.Body.Close() // nolint + + // Decode the response, unless the 'resp' output is nil. + if httpResp.Header.Get("Content-Type") != "application/json" { + return errors.New("not a JSON response") + } + if resp == nil { + return nil + } + return json.NewDecoder(httpResp.Body).Decode(resp) + }, backoff.WithContext(newExponentialBackOff(), ctx)) } // Initialize a new target sequence.