58 lines
1.5 KiB
Go
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())
|
|
}
|
|
}
|