Skip to content

Commit

Permalink
Merge pull request #67 from DIMO-Network/shared-retry-dynamic
Browse files Browse the repository at this point in the history
Add Retry Dinamic
  • Loading branch information
rhvivancoeffio committed May 9, 2024
2 parents 5d9f055 + 2fe01b2 commit 07a0d5f
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 5 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,5 @@ require (
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/text v0.14.0
)
28 changes: 26 additions & 2 deletions http_client_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type httpClientWrapper struct {
baseURL string
headers map[string]string
torProxyURL string
retry uint
}

type HTTPResponseError struct {
Expand All @@ -31,7 +32,7 @@ func BuildResponseError(statusCode int, err error) error {
return HTTPResponseError{StatusCode: statusCode, error: err}
}

func NewHTTPClientWrapper(baseURL, torProxyURL string, timeout time.Duration, headers map[string]string, addJSONHeaders bool) (HTTPClientWrapper, error) {
func NewHTTPClientWrapper(baseURL, torProxyURL string, timeout time.Duration, headers map[string]string, addJSONHeaders bool, opts ...HTTPClientWrapperOption) (HTTPClientWrapper, error) {
if headers == nil {
headers = map[string]string{}
}
Expand All @@ -49,14 +50,37 @@ func NewHTTPClientWrapper(baseURL, torProxyURL string, timeout time.Duration, he
}
client.Transport = &http.Transport{Proxy: http.ProxyURL(proxyURL)}
}

params := defaultHTTPClientWrapperOptions
for _, opt := range opts {
opt(&params)
}

return &httpClientWrapper{
httpClient: client,
baseURL: baseURL,
headers: headers,
torProxyURL: torProxyURL,
retry: params.Retry,
}, nil
}

type HTTPClientWrapperOptions struct {
Retry uint
}

var defaultHTTPClientWrapperOptions = HTTPClientWrapperOptions{
Retry: 5,
}

type HTTPClientWrapperOption func(*HTTPClientWrapperOptions)

func WithRetry(retry uint) HTTPClientWrapperOption {
return func(opts *HTTPClientWrapperOptions) {
opts.Retry = retry
}
}

// ExecuteRequest calls an endpoint, optional body and error handling. path is appended to the baseURL, same for json
// headers and authorization. If request results in non 2xx response, will always return error with payload body in err message.
// response should have defer response.Body.Close() after the error check as it could be nil when err is != nil
Expand Down Expand Up @@ -89,7 +113,7 @@ func (h httpClientWrapper) ExecuteRequest(path, method string, body []byte) (*ht
return errResp
}
return err
}, retry.Attempts(5), retry.Delay(500*time.Millisecond), retry.MaxDelay(9*time.Second))
}, retry.Attempts(h.retry), retry.Delay(500*time.Millisecond), retry.MaxDelay(9*time.Second))

if res == nil {
return nil, err
Expand Down
6 changes: 4 additions & 2 deletions http_client_wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

func Test_httpClientWrapper_ExecuteRequest_failsTooManyRetries(t *testing.T) {
const baseURL = "http://test.com"
hcw, _ := NewHTTPClientWrapper(baseURL, "", 1, nil, true)
retryCount := uint(5)

hcw, _ := NewHTTPClientWrapper(baseURL, "", 1, nil, true, WithRetry(retryCount))
httpmock.Activate()
defer httpmock.DeactivateAndReset()
path := "/api/vehicle/v2/makes"
Expand All @@ -19,7 +21,7 @@ func Test_httpClientWrapper_ExecuteRequest_failsTooManyRetries(t *testing.T) {
countInfo := httpmock.GetCallCountInfo()
c := countInfo["GET "+baseURL+path]

assert.Equal(t, 5, c, "expected five retries")
assert.Equal(t, int(retryCount), c, "expected five retries")
assert.Error(t, err, "expected error")
assert.ErrorIs(t, err, err.(HTTPResponseError), "expected HTTPResponseError")
assert.Equal(t, 503, err.(HTTPResponseError).StatusCode, "expected 409")
Expand Down

0 comments on commit 07a0d5f

Please sign in to comment.