Skip to content

Instantly share code, notes, and snippets.

@ricleal
Created January 28, 2024 21:17
Show Gist options
  • Save ricleal/68e6e17cdfea55f93d9c8f67e3e2533d to your computer and use it in GitHub Desktop.
Save ricleal/68e6e17cdfea55f93d9c8f67e3e2533d to your computer and use it in GitHub Desktop.
go rate limiter
package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"sync"
"time"
"golang.org/x/time/rate"
)
type RL struct {
client *http.Client
limiter *rate.Limiter
}
func NewRL(r, b int) *RL {
return &RL{
client: &http.Client{},
limiter: rate.NewLimiter(rate.Limit(r), b),
}
}
func (rl *RL) Get(ctx context.Context, url string) map[string]interface{} {
if !rl.limiter.Allow() {
err := rl.limiter.Wait(ctx)
if err != nil {
panic(err)
}
}
req, err := http.NewRequest("GET", url, http.NoBody)
if err != nil {
panic(err)
}
resp, err := rl.client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// convert response to map[string]interface{}
var response map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
panic(err)
}
return response
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// 10 requests per second
rl := NewRL(10, 1)
start := time.Now()
wg := sync.WaitGroup{}
for i := 0; i <= 100; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
resp := rl.Get(ctx, "https://httpbin.org/get")
fmt.Printf("Message %3d - %5dms -> %s\n", i, time.Since(start).Milliseconds(), resp["origin"])
}(i)
}
wg.Wait()
fmt.Println("Done")
}
// Output:
// Message 0 - 51ms -> 71.246.231.62
// Message 2 - 111ms -> 71.246.231.62
// Message 1 - 215ms -> 71.246.231.62
// Message 6 - 315ms -> 71.246.231.62
// Message 3 - 413ms -> 71.246.231.62
// Message 4 - 513ms -> 71.246.231.62
// Message 5 - 609ms -> 71.246.231.62
// Message 8 - 710ms -> 71.246.231.62
// Message 7 - 823ms -> 71.246.231.62
// Message 48 - 912ms -> 71.246.231.62
// Message 11 - 1013ms -> 71.246.231.62
// Message 13 - 1111ms -> 71.246.231.62
// Message 100 - 1210ms -> 71.246.231.62
// Message 49 - 1313ms -> 71.246.231.62
// Message 14 - 1418ms -> 71.246.231.62
// Message 12 - 1512ms -> 71.246.231.62
// Message 9 - 1612ms -> 71.246.231.62
// Message 76 - 1710ms -> 71.246.231.62
// Message 77 - 1812ms -> 71.246.231.62
// Message 50 - 1909ms -> 71.246.231.62
// Message 15 - 2011ms -> 71.246.231.62
// Message 78 - 2114ms -> 71.246.231.62
// Message 16 - 2211ms -> 71.246.231.62
// Message 10 - 2312ms -> 71.246.231.62
// Message 17 - 2410ms -> 71.246.231.62
// Message 18 - 2510ms -> 71.246.231.62
// Message 62 - 2607ms -> 71.246.231.62
// Message 19 - 2812ms -> 71.246.231.62
// Message 80 - 2910ms -> 71.246.231.62
// Message 20 - 3017ms -> 71.246.231.62
// Message 79 - 3043ms -> 71.246.231.62
// Message 81 - 3115ms -> 71.246.231.62
// Message 21 - 3212ms -> 71.246.231.62
// Message 51 - 3320ms -> 71.246.231.62
// Message 82 - 3412ms -> 71.246.231.62
// Message 22 - 3566ms -> 71.246.231.62
// Message 83 - 3611ms -> 71.246.231.62
// Message 52 - 3714ms -> 71.246.231.62
// Message 23 - 3811ms -> 71.246.231.62
// Message 53 - 3910ms -> 71.246.231.62
// Message 24 - 4009ms -> 71.246.231.62
// Message 55 - 4110ms -> 71.246.231.62
// Message 27 - 4211ms -> 71.246.231.62
// Message 56 - 4309ms -> 71.246.231.62
// Message 28 - 4410ms -> 71.246.231.62
// Message 75 - 4512ms -> 71.246.231.62
// Message 57 - 4619ms -> 71.246.231.62
// Message 29 - 4712ms -> 71.246.231.62
// Message 25 - 4809ms -> 71.246.231.62
// Message 54 - 4909ms -> 71.246.231.62
// Message 92 - 5009ms -> 71.246.231.62
// Message 58 - 5111ms -> 71.246.231.62
// Message 93 - 5216ms -> 71.246.231.62
// Message 94 - 5310ms -> 71.246.231.62
// Message 59 - 5410ms -> 71.246.231.62
// Message 60 - 5512ms -> 71.246.231.62
// Message 61 - 5609ms -> 71.246.231.62
// Message 38 - 5709ms -> 71.246.231.62
// Message 30 - 5812ms -> 71.246.231.62
// Message 31 - 5915ms -> 71.246.231.62
// Message 26 - 6011ms -> 71.246.231.62
// Message 32 - 6111ms -> 71.246.231.62
// Message 33 - 6211ms -> 71.246.231.62
// Message 64 - 6313ms -> 71.246.231.62
// Message 95 - 6411ms -> 71.246.231.62
// Message 63 - 6512ms -> 71.246.231.62
// Message 91 - 6612ms -> 71.246.231.62
// Message 70 - 6711ms -> 71.246.231.62
// Message 71 - 6890ms -> 71.246.231.62
// Message 39 - 6910ms -> 71.246.231.62
// Message 84 - 7010ms -> 71.246.231.62
// Message 96 - 7114ms -> 71.246.231.62
// Message 35 - 7212ms -> 71.246.231.62
// Message 85 - 7311ms -> 71.246.231.62
// Message 86 - 7410ms -> 71.246.231.62
// Message 36 - 7510ms -> 71.246.231.62
// Message 34 - 7611ms -> 71.246.231.62
// Message 40 - 7709ms -> 71.246.231.62
// Message 97 - 7811ms -> 71.246.231.62
// Message 37 - 7909ms -> 71.246.231.62
// Message 72 - 8010ms -> 71.246.231.62
// Message 98 - 8111ms -> 71.246.231.62
// Message 73 - 8211ms -> 71.246.231.62
// Message 41 - 8309ms -> 71.246.231.62
// Message 42 - 8414ms -> 71.246.231.62
// Message 87 - 8513ms -> 71.246.231.62
// Message 90 - 8609ms -> 71.246.231.62
// Message 45 - 8713ms -> 71.246.231.62
// Message 43 - 8813ms -> 71.246.231.62
// Message 99 - 8912ms -> 71.246.231.62
// Message 44 - 9011ms -> 71.246.231.62
// Message 89 - 9115ms -> 71.246.231.62
// Message 74 - 9210ms -> 71.246.231.62
// Message 88 - 9314ms -> 71.246.231.62
// Message 47 - 9409ms -> 71.246.231.62
// Message 46 - 9510ms -> 71.246.231.62
// Message 66 - 9613ms -> 71.246.231.62
// Message 67 - 9714ms -> 71.246.231.62
// Message 68 - 9812ms -> 71.246.231.62
// Message 65 - 10013ms -> 71.246.231.62
// Message 69 - 10182ms -> 71.246.231.62
// Done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment