Skip to content

Commit 4311699

Browse files
committed
feat!: add overwrite ability for retry conditions and hooks #868
- refactor retry conditions and hooks into accepting multiple values
1 parent 29797dd commit 4311699

File tree

5 files changed

+143
-49
lines changed

5 files changed

+143
-49
lines changed

client.go

+19-11
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,8 @@ func (c *Client) R() *Request {
646646
debugLogCurlCmd: c.debugLogCurlCmd,
647647
unescapeQueryParams: c.unescapeQueryParams,
648648
credentials: c.credentials,
649+
retryConditions: slices.Clone(c.retryConditions),
650+
retryHooks: slices.Clone(c.retryHooks),
649651
}
650652

651653
if c.ctx != nil {
@@ -1362,16 +1364,18 @@ func (c *Client) RetryConditions() []RetryConditionFunc {
13621364
return c.retryConditions
13631365
}
13641366

1365-
// AddRetryCondition method adds a retry condition function to an array of functions
1366-
// that are checked to determine if the request is retried. The request will
1367-
// retry if any functions return true and the error is nil.
1367+
// AddRetryConditions method adds one or more retry condition functions into the request.
1368+
// These retry conditions are executed to determine if the request can be retried.
1369+
// The request will retry if any functions return `true`, otherwise return `false`.
13681370
//
1369-
// NOTE: These retry conditions are applied on all requests made using this Client.
1370-
// For [Request] specific retry conditions, check [Request.AddRetryCondition]
1371-
func (c *Client) AddRetryCondition(condition RetryConditionFunc) *Client {
1371+
// NOTE:
1372+
// - The client-level retry conditions are applied to all requests.
1373+
// - The request-level retry conditions are executed first before client-level
1374+
// retry conditions. See [Request.AddRetryConditions], [Request.SetRetryConditions]
1375+
func (c *Client) AddRetryConditions(conditions ...RetryConditionFunc) *Client {
13721376
c.lock.Lock()
13731377
defer c.lock.Unlock()
1374-
c.retryConditions = append(c.retryConditions, condition)
1378+
c.retryConditions = append(c.retryConditions, conditions...)
13751379
return c
13761380
}
13771381

@@ -1382,12 +1386,16 @@ func (c *Client) RetryHooks() []RetryHookFunc {
13821386
return c.retryHooks
13831387
}
13841388

1385-
// AddRetryHook adds a side-effecting retry hook to an array of hooks
1386-
// that will be executed on each retry.
1387-
func (c *Client) AddRetryHook(hook RetryHookFunc) *Client {
1389+
// AddRetryHooks method adds one or more side-effecting retry hooks to an array
1390+
// of hooks that will be executed on each retry.
1391+
//
1392+
// NOTE:
1393+
// - All the retry hooks are executed on request retry.
1394+
// - The request-level retry hooks are executed first before client-level hooks.
1395+
func (c *Client) AddRetryHooks(hooks ...RetryHookFunc) *Client {
13881396
c.lock.Lock()
13891397
defer c.lock.Unlock()
1390-
c.retryHooks = append(c.retryHooks, hook)
1398+
c.retryHooks = append(c.retryHooks, hooks...)
13911399
return c
13921400
}
13931401

client_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ func TestClientSettingsCoverage(t *testing.T) {
518518
assertEqual(t, time.Millisecond*100, c.RetryWaitTime())
519519
assertEqual(t, time.Second*2, c.RetryMaxWaitTime())
520520
assertEqual(t, false, c.IsTrace())
521+
assertEqual(t, 0, len(c.RetryConditions()))
521522

522523
authToken := "sample auth token value"
523524
c.SetAuthToken(authToken)
@@ -1144,7 +1145,7 @@ func TestClientOnResponseError(t *testing.T) {
11441145
SetAuthToken("004DDB79-6801-4587-B976-F093E6AC44FF").
11451146
SetRetryCount(0).
11461147
SetRetryMaxWaitTime(time.Microsecond).
1147-
AddRetryCondition(func(response *Response, err error) bool {
1148+
AddRetryConditions(func(response *Response, err error) bool {
11481149
if err != nil {
11491150
return true
11501151
}

request.go

+40-11
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ type Request struct {
9494
multipartBoundary string
9595
multipartFields []*MultipartField
9696
retryConditions []RetryConditionFunc
97+
retryHooks []RetryHookFunc
9798
resultCurlCmd string
9899
generateCurlCmd bool
99100
debugLogCurlCmd bool
@@ -945,14 +946,43 @@ func (r *Request) SetDebug(d bool) *Request {
945946
return r
946947
}
947948

948-
// AddRetryCondition method adds a retry condition function to the request's
949-
// array of functions is checked to determine if the request can be retried.
950-
// The request will retry if any functions return true and the error is nil.
949+
// AddRetryConditions method adds one or more retry condition functions into the request.
950+
// These retry conditions are executed to determine if the request can be retried.
951+
// The request will retry if any functions return `true`, otherwise return `false`.
951952
//
952-
// NOTE: The request level retry conditions are checked before all retry
953-
// conditions from the client instance.
954-
func (r *Request) AddRetryCondition(condition RetryConditionFunc) *Request {
955-
r.retryConditions = append(r.retryConditions, condition)
953+
// NOTE:
954+
// - The client-level retry conditions are applied to all requests.
955+
// - The request-level retry conditions are executed first before client-level
956+
// retry conditions. See [Request.SetRetryConditions]
957+
func (r *Request) AddRetryConditions(conditions ...RetryConditionFunc) *Request {
958+
r.retryConditions = append(r.retryConditions, conditions...)
959+
return r
960+
}
961+
962+
// SetRetryConditions method overwrites the retry conditions in the request.
963+
// These retry conditions are executed to determine if the request can be retried.
964+
// The request will retry if any function returns `true`, otherwise return `false`.
965+
func (r *Request) SetRetryConditions(conditions ...RetryConditionFunc) *Request {
966+
r.retryConditions = conditions
967+
return r
968+
}
969+
970+
// AddRetryHooks method adds one or more side-effecting retry hooks in the request.
971+
//
972+
// NOTE:
973+
// - All the retry hooks are executed on each request retry.
974+
// - The request-level retry hooks are executed first before client-level hooks.
975+
func (r *Request) AddRetryHooks(hooks ...RetryHookFunc) *Request {
976+
r.retryHooks = append(r.retryHooks, hooks...)
977+
return r
978+
}
979+
980+
// SetRetryHooks method overwrites side-effecting retry hooks in the request.
981+
//
982+
// NOTE:
983+
// - All the retry hooks are executed on each request retry.
984+
func (r *Request) SetRetryHooks(hooks ...RetryHookFunc) *Request {
985+
r.retryHooks = hooks
956986
return r
957987
}
958988

@@ -1355,8 +1385,7 @@ func (r *Request) Execute(method, url string) (res *Response, err error) {
13551385
// is still false
13561386
if !needsRetry && res != nil {
13571387
// user defined retry conditions
1358-
retryConditions := append(r.retryConditions, r.client.RetryConditions()...)
1359-
for _, retryCondition := range retryConditions {
1388+
for _, retryCondition := range r.retryConditions {
13601389
if needsRetry = retryCondition(res, err); needsRetry {
13611390
break
13621391
}
@@ -1375,7 +1404,7 @@ func (r *Request) Execute(method, url string) (res *Response, err error) {
13751404
}
13761405

13771406
// run user-defined retry hooks
1378-
for _, retryHookFunc := range r.client.RetryHooks() {
1407+
for _, retryHookFunc := range r.retryHooks {
13791408
retryHookFunc(res, err)
13801409
}
13811410

@@ -1393,11 +1422,11 @@ func (r *Request) Execute(method, url string) (res *Response, err error) {
13931422
select {
13941423
case <-r.Context().Done():
13951424
isCtxDone = true
1396-
timer.Stop()
13971425
err = wrapErrors(r.Context().Err(), err)
13981426
break
13991427
case <-timer.C:
14001428
}
1429+
timer.Stop()
14011430
if isCtxDone {
14021431
break
14031432
}

request_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2137,7 +2137,7 @@ func TestRequestNoRetryOnNonIdempotentMethod(t *testing.T) {
21372137

21382138
c := dcnl().
21392139
SetTimeout(time.Second * 3).
2140-
AddRetryHook(
2140+
AddRetryHooks(
21412141
func(response *Response, _ error) {
21422142
read, err := bufReader.Read(bufCpy)
21432143

0 commit comments

Comments
 (0)