Rate Limiter
Token bucket rate limiter for controlling request rates
Description
A token bucket rate limiter implementation in Go. Controls the rate of operations by maintaining a bucket of tokens that refill over time.
Features
- Token bucket algorithm
- Configurable rate and burst size
- Thread-safe operations
- Time-based token refill
Code
package ratelimitimport ( "sync" "time")type RateLimiter struct { mu sync.Mutex tokens float64 maxTokens float64 refillRate float64 lastRefill time.Time}func NewRateLimiter(rate float64, burst int) *RateLimiter { return &RateLimiter{ tokens: float64(burst), maxTokens: float64(burst), refillRate: rate, lastRefill: time.Now(), }}func (rl *RateLimiter) refill() { now := time.Now() elapsed := now.Sub(rl.lastRefill).Seconds() tokensToAdd := elapsed * rl.refillRate rl.mu.Lock() defer rl.mu.Unlock() rl.tokens = min(rl.tokens+tokensToAdd, rl.maxTokens) rl.lastRefill = now}func (rl *RateLimiter) Allow() bool { rl.refill() rl.mu.Lock() defer rl.mu.Unlock() if rl.tokens >= 1.0 { rl.tokens -= 1.0 return true } return false}func (rl *RateLimiter) Wait(ctx context.Context) error { for !rl.Allow() { select { case <-ctx.Done(): return ctx.Err() case <-time.After(time.Second / time.Duration(rl.refillRate)): } } return nil}func min(a, b float64) float64 { if a < b { return a } return b}
package mainimport ( "context" "fmt" "time" "ratelimit")func main() { limiter := ratelimit.NewRateLimiter(10, 20) ctx := context.Background() for i := 0; i < 50; i++ { if limiter.Allow() { fmt.Printf("Request %d allowed\n", i+1) } else { fmt.Printf("Request %d rate limited\n", i+1) limiter.Wait(ctx) } }}
Comments
No comments yet. Be the first to comment!
Please login to leave a comment.