From 7909ab12bf063ae12251f6773e7adf0e58e56559 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Date: Tue, 10 Jun 2025 15:59:32 +0530 Subject: [PATCH] feat: RetryAttempt in PrepareRetry hook Adding the `retryAttempt` counter, which refers to the current retry attempt to enable the server and client to make an informed decision to process the request. For example, - The client can hit a fallback host (server) based on the retry attempt. - The client can send the retry count in the header, and the server can process the request in any special way. --- client.go | 13 ++++++++++--- client_test.go | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/client.go b/client.go index 4b04533..ab080dc 100644 --- a/client.go +++ b/client.go @@ -398,8 +398,15 @@ type Backoff func(min, max time.Duration, attemptNum int, resp *http.Response) t // attempted. If overriding this, be sure to close the body if needed. type ErrorHandler func(resp *http.Response, err error, numTries int) (*http.Response, error) -// PrepareRetry is called before retry operation. It can be used for example to re-sign the request -type PrepareRetry func(req *http.Request) error +// PrepareRetry is called before the retry operation. It can be used, for example, +// to re-sign the request. After version 0.7.7, PrepareRetry takes the retryAttempt, +// a one-based counter that refers to the current retry attempt. The retryAttempt +// counter would help the server and clients make informed decisions. For example, +// - The client can send a request to a fallback host (server) after a certain number +// of retries. +// - The client can send the retry attempt in the request header, which would help +// the server to process the request in any special way if needed. +type PrepareRetry func(req *http.Request, retryAttempt int) error // Client is used to make HTTP requests. It adds additional functionality // like automatic retries to tolerate minor outages. @@ -779,7 +786,7 @@ func (c *Client) Do(req *Request) (*http.Response, error) { req.Request = &httpreq if c.PrepareRetry != nil { - if err := c.PrepareRetry(req.Request); err != nil { + if err := c.PrepareRetry(req.Request, attempt); err != nil { prepareErr = err break } diff --git a/client_test.go b/client_test.go index d12cd1b..5cb9654 100644 --- a/client_test.go +++ b/client_test.go @@ -376,9 +376,9 @@ func TestClient_Do_WithPrepareRetry(t *testing.T) { } var prepareChecks int - client.PrepareRetry = func(req *http.Request) error { + client.PrepareRetry = func(req *http.Request, retryAttempt int) error { prepareChecks++ - req.Header.Set("foo", strconv.Itoa(prepareChecks)) + req.Header.Set("foo", strconv.Itoa(retryAttempt)) return nil }