You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

48 lines
917 B

  1. package ratelimit
  2. import "net/http"
  3. // Throttle is a middleware that limits number of currently
  4. // processed requests at a time.
  5. func Throttle(limit int) func(http.Handler) http.Handler {
  6. if limit <= 0 {
  7. panic("Throttle expects limit > 0")
  8. }
  9. t := throttler{
  10. tokens: make(chan token, limit),
  11. }
  12. for i := 0; i < limit; i++ {
  13. t.tokens <- token{}
  14. }
  15. fn := func(h http.Handler) http.Handler {
  16. t.h = h
  17. return &t
  18. }
  19. return fn
  20. }
  21. // token represents a request that is being processed.
  22. type token struct{}
  23. // throttler limits number of currently processed requests at a time.
  24. type throttler struct {
  25. h http.Handler
  26. tokens chan token
  27. }
  28. // ServeHTTP implements http.Handler interface.
  29. func (t *throttler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  30. select {
  31. case <-r.Context().Done():
  32. return
  33. case tok := <-t.tokens:
  34. defer func() {
  35. t.tokens <- tok
  36. }()
  37. t.h.ServeHTTP(w, r)
  38. }
  39. }