Includes solved 02-worker-pool and 09-safe-counter (mutex, atomic, sharded). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GbnJj9ZqEx9nUvzkjdwfMq
46 lines
1.3 KiB
Go
46 lines
1.3 KiB
Go
// Exercise 03 — Token Bucket Rate Limiter
|
|
//
|
|
// ASSIGNMENT
|
|
// ----------
|
|
// Implement a token-bucket limiter:
|
|
//
|
|
// 1. NewLimiter(rate, burst): capacity `burst` tokens, refilled continuously
|
|
// at `rate` tokens/second. Bucket starts FULL.
|
|
// 2. Allow() consumes one token and returns true, or returns false if no
|
|
// token is available. Must be non-blocking and safe for concurrent use.
|
|
// 3. Refill must be LAZY — no background goroutine, no ticker. Compute the
|
|
// accrued tokens from elapsed time inside Allow().
|
|
// 4. Tokens never exceed `burst` (idle time must not build infinite credit).
|
|
//
|
|
// Run the tests: go test -race ./03-rate-limiter/
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
type Limiter struct {
|
|
// TODO: fields (mutex, current tokens, max, rate, last refill 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{}
|
|
}
|
|
|
|
// Allow reports whether one operation may proceed now.
|
|
// TODO: implement me.
|
|
func (l *Limiter) Allow() bool {
|
|
return false
|
|
}
|
|
|
|
func main() {
|
|
l := NewLimiter(5, 3) // 5/sec, burst 3
|
|
for i := 0; i < 10; i++ {
|
|
fmt.Printf("req %d: allowed=%v\n", i, l.Allow())
|
|
time.Sleep(100 * time.Millisecond)
|
|
}
|
|
}
|