Created
December 18, 2023 15:31
-
-
Save chmike/a85c77cd4725ce052a6cb10d6381655c to your computer and use it in GitHub Desktop.
Revisions
-
chmike created this gist
Dec 18, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,43 @@ // NewRateLimiter returns a rate limiter function returning false // when the event must be rejected, and true when it must be accepted. // The rate is expressed in Hz (events/seconds). It simply ensures that // the time interval between two accept satisfies the rate criteria. It // is equivalent to the token bucket algorithm with a bucket size of one. func NewRateLimiter(rate float64) func() bool { var stamp time.Time // time stamp of last accepted event return func() bool { now := time.Now() if now.Sub(stamp).Seconds() *rate < 1. { return false } stamp = now return true } } // The following is a usage example with a rate limiting middelware. func rateLimiter(rate float64, f http.HandlerFunc) http.HandlerFunc { rl := NewRateLimiter(rate) return func(w http.ResponseWriter, r *http.Request) { if !rl() { http.Error(w, "too many requests, retry later", http.StatusTooManyRequests) return } f(w, r) } } // some example server action func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "hello !") } func main() { http.HandleFunc("/", rateLimiter(1, hello)) // accept at most one request per second http.ListenAndServe(":8080", nil) }