Skip to content

Instantly share code, notes, and snippets.

@mattbajorek
Last active August 16, 2022 18:34
Show Gist options
  • Save mattbajorek/be2f01cf8d4b160183a018a19c45101e to your computer and use it in GitHub Desktop.
Save mattbajorek/be2f01cf8d4b160183a018a19c45101e to your computer and use it in GitHub Desktop.
Max requests per second limiter
package main
import (
"fmt"
"sync"
"time"
)
func main() {
// Start request limiter
// Only 10 requests are able to be sent out in every second interval
maxRequestPerSecondLimiterChannel := maxRequestsPerSecondLimiter(10)
var waitGroup sync.WaitGroup
for i := 0; i < 50; i++ {
waitGroup.Add(1)
go func(id int) {
fmt.Printf("Waiting to request %d\n", id)
// Will wait until below limit of requests per second
maxRequestPerSecondLimiterChannel <- true
fmt.Printf("Making request %d\n", id)
<-time.After(3 * time.Second)
fmt.Printf("Maked request %d\n", id)
waitGroup.Done()
}(i)
}
waitGroup.Wait()
}
func maxRequestsPerSecondLimiter(requestsPerSecond uint) chan bool {
maxRequestsPerSecondLimiterChannel := make(chan bool, requestsPerSecond)
// 1. If channel is fully available -> for loop will block
// 2. If channnel has at least one value -> allow another request after a second
// for desired amount of requests per second
for i := uint(0); i < requestsPerSecond; i++ {
go func() {
for {
<-time.After(time.Second)
<-maxRequestsPerSecondLimiterChannel
}
}()
}
return maxRequestsPerSecondLimiterChannel
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment