Skip to content

Instantly share code, notes, and snippets.

@brownhash
Last active December 5, 2021 14:27
Show Gist options
  • Save brownhash/e074ea2536cec42da07ea486a6812fc4 to your computer and use it in GitHub Desktop.
Save brownhash/e074ea2536cec42da07ea486a6812fc4 to your computer and use it in GitHub Desktop.
Implementing rate limiting on api
package main
import (
"errors"
"time"
"net/http"
)
// Struct to hold channels
type PressureGauge struct {
ch chan struct{}
}
// Function on above struct to apply pressure
func (pg *PressureGauge) ApplyLimit(f func()) error {
select {
// receive struct values from PressureGauge
case <-pg.ch:
// execute the passed function
f()
// refill the PressureGauge
pg.ch <- struct{}{}
return nil
default:
// raise error if PressureGauge's capacity is exhausted
return errors.New("no more capacity")
}
}
// Function to initiate limits using the struct
func SetLimit(limit int) *PressureGauge {
// initiate channels
ch := make(chan struct{}, limit)
// fill up channel capacity
for i := 0 ; i < limit ; i++ {
ch <- struct{}{}
}
return &PressureGauge{
ch: ch,
}
}
// Applying rate limiting on requests
func main() {
// initiate rate limit
pg := SetLimit(5)
http.HandleFunc("/request", func(w http.ResponseWriter, r *http.Request){
err := pg.ApplyLimit(func() {
w.Write([]byte(doLimitedStuff()))
})
if err != nil {
w.WriteHeader(http.StatusTooManyRequests)
w.Write([]byte("too many requests"))
}
})
http.ListenAndServe(":8080", nil)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment