Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
81 lines (64 sloc) 2.68 KB
/*
Title: 35.Rate_Limiting.go
Author: OpenSource
Date: 2017-05-21
Description: For Study
Rate limiting is an important mechanism for controlling resource utilization
and maintaining quality of service. Go elegantly supports rate limiting
with goroutines, channels, and tickers[exam - 33].
*/
package main
import "time"
import "fmt"
func main(){
fmt.Println("35.Rate_Limiting.go---------Start------------\n\n")
// First we’ll look at basic rate limiting.
// Suppose we want to limit our handling of incoming requests.
// We’ll serve these requests off a channel of the same name.
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 our rate limiting scheme.
limiter := time.Tick(time.Millisecond * 200)
// By blocking on a receive from the limiter channel before serving each request,
// we limit ourselves to 1 request every 200 milliseconds.
for req := range requests{
fmt.Println("<- limiter => ", <-limiter)
fmt.Println("request: ",req,"time.Now() =>", time.Now())
}
// We may want to allow short bursts of requests in our rate limiting scheme
// while preserving the overall rate limit.
// We can accomplish this by buffering our limiter channel.
// This burstyLimiter channel will allow bursts of up to 3 events.
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 we’ll try to add a new value to burstyLimiter, up to its limit of 3.
go func(){
for t := range time.Tick(time.Millisecond * 200){
fmt.Println("t := range time.Tick(time.Millisecond *200) => ", t)
burstyLimiter <- t
}
}()
// Now 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{
fmt.Println("<- burstyLimiter =>", <- burstyLimiter)
fmt.Println("request: ", req, time.Now())
}
fmt.Println("\n\n35.Rate_Limiting.go----------End-------------")
// Running our program we see the first batch of requests handled
// once every ~200 milliseconds as desired.
// For the second batch of requests we serve the first 3 immediately
// because of the burstable rate limiting, then serve the remaining 2 with ~200ms delays each.
}
You can’t perform that action at this time.