mirror of
https://github.com/imjasonh/staticmaps
synced 2026-07-18 14:56:16 +00:00
Add backoff http.RoundTripper that that handles exponential backoff
This commit is contained in:
parent
41f9b8b763
commit
f9c0e3df19
3 changed files with 85 additions and 1 deletions
47
backoff.go
Normal file
47
backoff.go
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
package maps
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type backoff struct {
|
||||
Transport *http.RoundTripper
|
||||
MaxTries int
|
||||
tries int
|
||||
sleep func(time.Duration)
|
||||
}
|
||||
|
||||
func (bt *backoff) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if bt.Transport == nil {
|
||||
bt.Transport = &http.DefaultTransport
|
||||
}
|
||||
if bt.MaxTries == 0 {
|
||||
bt.MaxTries = 5
|
||||
}
|
||||
if bt.sleep == nil {
|
||||
bt.sleep = time.Sleep
|
||||
}
|
||||
wait := time.Second
|
||||
var err error
|
||||
for ; bt.tries < bt.MaxTries; bt.tries++ {
|
||||
var resp *http.Response
|
||||
resp, err = (*bt.Transport).RoundTrip(req)
|
||||
if err != nil {
|
||||
// fallthrough, retry
|
||||
} else if resp.StatusCode >= http.StatusInternalServerError {
|
||||
err = HTTPError{resp}
|
||||
} else {
|
||||
return resp, nil
|
||||
}
|
||||
if bt.tries == bt.MaxTries-1 {
|
||||
// last try failed, just give up
|
||||
continue
|
||||
}
|
||||
bt.sleep(wait)
|
||||
jitter := time.Duration(rand.Intn(1000))*time.Millisecond - 500*time.Millisecond // jitter is +/- .5s
|
||||
wait = wait*2 + jitter
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue