38 lines
1.0 KiB
Go
38 lines
1.0 KiB
Go
package http
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"math/rand"
|
|
"net/http"
|
|
)
|
|
|
|
func (s *Server) rateLimiter(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
token, err := s.RateLimiter.Acquire()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
ctx := context.WithValue(r.Context(), "rate-limit-token", token)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
func (s *Server) faulty(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
rlExceedPerc := s.RateLimiter.LimitExceededPerc()
|
|
// Faults will scale to the percentage of requests that are above the limit.
|
|
// When 2x volume is exceeded all requests should fail.
|
|
if rlExceedPerc > 0.0 {
|
|
check := rand.Float32()
|
|
if rlExceedPerc > float32(check) {
|
|
s.respondError(w, http.StatusInternalServerError, errors.New("application error"))
|
|
// Transaction failed so release the token.
|
|
s.RateLimiter.Release(r.Context().Value("rate-limit-token").(*Token))
|
|
return
|
|
}
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|