Files
go_playground/5-go-by-example/37-rate-limiting.go
2022-01-11 14:50:17 +01:00

58 lines
1.5 KiB
Go

package main
import (
"fmt"
"time"
)
// controlling resource utilization and maintaining quality of service
func main() {
// basic rate limiting
// want to limit handling of incoming requests
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)
// this limiter channel will receive a value every 200 milliseconds
// this is the regulator in the rate limiting scheme.
limiter := time.Tick(200 * time.Millisecond)
// by blocking on a receive from the limiter channel before serving each request,
// limit to 1 request every 200 milliseconds
for req := range requests {
<-limiter
fmt.Println("request", req, time.Now())
}
// allow short bursts of requests in rate limiting scheme while preserving the overall rate limit
// accomplish this by buffering the limiter channel
burstyLimiter := make(chan time.Time, 3)
// fill up the channel to represent allowed bursting
for i := 0; i < 3; i++ {
burstyLimiter <- time.Now()
}
// every 200 milliseconds try to add a new value to burstyLimiter, up to its limit of 3
go func() {
for t := range time.Tick(200 * time.Millisecond) {
burstyLimiter <- t
}
}()
// simulate 5 more incoming requests
// the first 3 of these will benefit from the burst capability of burstyLimiter
burstyRequests := make(chan int, 5)
for i := 1; i <= 5; i++ {
burstyRequests <- i
}
close(burstyRequests)
for req := range burstyRequests {
<-burstyLimiter
fmt.Println("request", req, time.Now())
}
}