Skip to content

Commit

Permalink
Add retry handler to respect retry-after <date>
Browse files Browse the repository at this point in the history
  • Loading branch information
rkodev committed May 9, 2024
1 parent 75e4bec commit 08e5738
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

### Changed
## [1.4.0] - 2024-05-09

- Support retry after as a date.

## [1.3.3] - 2024-03-19

Expand Down
8 changes: 7 additions & 1 deletion retry_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ func (middleware RetryHandler) getRetryDelay(req *nethttp.Request, resp *nethttp
if err == nil {
return time.Duration(retryAfterDelay) * time.Second
}
} //TODO parse the header if it's a date

// parse the header if it's a date
t, err := time.Parse(time.RFC1123, retryAfter)
if err == nil {
return t.Sub(time.Now())
}
}
return time.Duration(math.Pow(float64(options.GetDelaySeconds()), float64(executionCount))) * time.Second
}
28 changes: 28 additions & 0 deletions retry_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,34 @@ func TestItHonoursMaxRetries(t *testing.T) {
assert.Equal(t, defaultMaxRetries, retryAttemptInt)
}

func TestItHonoursRetryAfterDate(t *testing.T) {
retryAttemptInt := -1
start := time.Now()
retryAfterTimeStr := start.Add(4 * time.Second).Format(time.RFC1123)
testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) {
res.Header().Set("Retry-After", retryAfterTimeStr)
res.WriteHeader(429)
retryAttemptInt++
res.Write([]byte("body"))
}))

defer func() { testServer.Close() }()
handler := NewRetryHandler()
req, err := nethttp.NewRequest(nethttp.MethodGet, testServer.URL, nil)
if err != nil {
t.Error(err)
}
resp, err := handler.Intercept(newNoopPipeline(), 0, req)
if err != nil {
t.Error(err)
}
assert.NotNil(t, resp)
end := time.Now()

assert.Equal(t, defaultMaxRetries, retryAttemptInt)
assert.Greater(t, end.Sub(start), 3*time.Second) // delay should be greater than 3 seconds (ignoring microsecond differences)
}

func TestItHonoursContextExpiry(t *testing.T) {
retryAttemptInt := -1
testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) {
Expand Down

0 comments on commit 08e5738

Please sign in to comment.