diff --git a/lib/promscrape/client.go b/lib/promscrape/client.go index 388736370..d8a9701da 100644 --- a/lib/promscrape/client.go +++ b/lib/promscrape/client.go @@ -152,21 +152,19 @@ var ( ) func doRequestWithPossibleRetry(hc *fasthttp.HostClient, req *fasthttp.Request, resp *fasthttp.Response, deadline time.Time) error { - attempts := 0 -again: - // Use DoDeadline instead of Do even if hc.ReadTimeout is already set in order to guarantee the given deadline - // across multiple retries. - err := hc.DoDeadline(req, resp, deadline) - if err == nil { - return nil + for { + // Use DoDeadline instead of Do even if hc.ReadTimeout is already set in order to guarantee the given deadline + // across multiple retries. + err := hc.DoDeadline(req, resp, deadline) + if err == nil { + return nil + } + if err != fasthttp.ErrConnectionClosed { + return err + } + // Retry request if the server closes the keep-alive connection unless deadline exceeds. + if time.Since(deadline) >= 0 { + return fmt.Errorf("the server closes all the connection attempts: %w", err) + } } - if err != fasthttp.ErrConnectionClosed { - return err - } - // Retry request if the server closes the keep-alive connection unless deadline exceeds. - attempts++ - if attempts > 3 { - return fmt.Errorf("the server closed 3 subsequent connections: %w", err) - } - goto again } diff --git a/lib/promscrape/discoveryutils/client.go b/lib/promscrape/discoveryutils/client.go index 99f557b97..f0bc4b592 100644 --- a/lib/promscrape/discoveryutils/client.go +++ b/lib/promscrape/discoveryutils/client.go @@ -110,8 +110,8 @@ func (c *Client) GetAPIResponse(path string) ([]byte, error) { req.Header.Set("Authorization", c.ac.Authorization) } var resp fasthttp.Response - // There is no need in calling DoTimeout, since the timeout is already set in c.hc.ReadTimeout above. - if err := c.hc.Do(&req, &resp); err != nil { + deadline := time.Now().Add(c.hc.ReadTimeout) + if err := doRequestWithPossibleRetry(c.hc, &req, &resp, deadline); err != nil { return nil, fmt.Errorf("cannot fetch %q: %w", requestURL, err) } var data []byte @@ -131,3 +131,21 @@ func (c *Client) GetAPIResponse(path string) ([]byte, error) { } return data, nil } + +func doRequestWithPossibleRetry(hc *fasthttp.HostClient, req *fasthttp.Request, resp *fasthttp.Response, deadline time.Time) error { + for { + // Use DoDeadline instead of Do even if hc.ReadTimeout is already set in order to guarantee the given deadline + // across multiple retries. + err := hc.DoDeadline(req, resp, deadline) + if err == nil { + return nil + } + if err != fasthttp.ErrConnectionClosed { + return err + } + // Retry request if the server closes the keep-alive connection unless deadline exceeds. + if time.Since(deadline) >= 0 { + return fmt.Errorf("the server closes all the connection attempts: %w", err) + } + } +}