03-rate-limiter: implement token bucket Limiter with step-by-step comments
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GbnJj9ZqEx9nUvzkjdwfMq
This commit is contained in:
+30
-1
@@ -17,22 +17,51 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Limiter struct {
|
||||
|
||||
// TODO: fields (mutex, current tokens, max, rate, last refill time)
|
||||
mu sync.Mutex
|
||||
tokens float64
|
||||
max float64
|
||||
rate float64
|
||||
last time.Time
|
||||
}
|
||||
|
||||
// NewLimiter returns a limiter allowing `rate` ops/sec with bursts up to `burst`.
|
||||
// TODO: implement me.
|
||||
func NewLimiter(rate float64, burst int) *Limiter {
|
||||
return &Limiter{}
|
||||
return &Limiter{tokens: float64(burst), rate: rate, max: float64(burst), last: time.Now()}
|
||||
}
|
||||
|
||||
// Allow reports whether one operation may proceed now.
|
||||
// TODO: implement me.
|
||||
func (l *Limiter) Allow() bool {
|
||||
/*
|
||||
1. Lock — refill + consume is a read-modify-write on two fields;
|
||||
without the lock two goroutines can both see 1 token and both take it.
|
||||
2. Lazy refill — tokens earned since the last call = elapsed * rate.
|
||||
float64 so fractions (0.6 of a token) carry over instead of truncating to 0.
|
||||
3. Cap at max — idle time must not build unlimited credit (burst is a ceiling).
|
||||
4. Update last on EVERY call, granted or not — otherwise the same interval
|
||||
is credited again on the next call.
|
||||
5. If at least one whole token is available, take it and allow; else deny.
|
||||
Non-blocking: never sleeps or waits.
|
||||
*/
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
l.tokens += l.rate * time.Since(l.last).Seconds()
|
||||
if l.tokens > l.max {
|
||||
l.tokens = l.max
|
||||
}
|
||||
l.last = time.Now()
|
||||
if l.tokens >= 1 {
|
||||
l.tokens--
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user