mirror of https://github.com/k3s-io/k3s
Add a Retry-After header when rate limit is exceeded
parent
b5bc0c1619
commit
8350bb9700
|
@ -72,6 +72,7 @@ func RateLimit(rl util.RateLimiter, handler http.Handler) http.Handler {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.WriteHeader(http.StatusServiceUnavailable)
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
w.Header().Set("Retry-After", "1")
|
||||||
fmt.Fprintf(w, "Rate limit exceeded.")
|
fmt.Fprintf(w, "Rate limit exceeded.")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import (
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
|
||||||
watchjson "github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
|
watchjson "github.com/GoogleCloudPlatform/kubernetes/pkg/watch/json"
|
||||||
|
"github.com/golang/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
// specialParams lists parameters that are handled specially and which users of Request
|
// specialParams lists parameters that are handled specially and which users of Request
|
||||||
|
@ -457,6 +458,10 @@ func (r *Request) Do() Result {
|
||||||
client = http.DefaultClient
|
client = http.DefaultClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Right now we make about ten retry attempts if we get a Retry-After response.
|
||||||
|
// TODO: Change to a timeout based approach.
|
||||||
|
retries := 0
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return Result{err: &RequestConstructionError{r.err}}
|
return Result{err: &RequestConstructionError{r.err}}
|
||||||
|
@ -478,6 +483,19 @@ func (r *Request) Do() Result {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode == http.StatusServiceUnavailable {
|
||||||
|
if retries < 10 {
|
||||||
|
retries++
|
||||||
|
if waitFor := resp.Header.Get("Retry-After"); waitFor != "" {
|
||||||
|
delay, err := strconv.Atoi(waitFor)
|
||||||
|
if err == nil {
|
||||||
|
glog.V(4).Infof("Got a Retry-After %s response for attempt %d to %v", waitFor, retries, r.finalURL())
|
||||||
|
time.Sleep(time.Duration(delay) * time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return Result{respBody, created, err, r.codec}
|
return Result{respBody, created, err, r.codec}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue