Documentation
¶
Overview ¶
Package ratelimit provides a token-bucket rate limiter adapter that implements the runtime/http/middleware.RateLimiter and WindowedRateLimiter interfaces using golang.org/x/time/rate.
Each unique key (typically client IP) gets its own token bucket, providing per-IP rate limiting. Stale buckets are periodically cleaned up to prevent memory leaks from ephemeral IPs.
ref: golang.org/x/time/rate — token bucket algorithm Adopted: rate.NewLimiter for per-key token bucket. Deviated: wrapped behind middleware.RateLimiter/WindowedRateLimiter so runtime/ remains decoupled from x/time imports.
Package ratelimit implements a per-key in-process token bucket rate limiter.
The bucket math (refill, burst cap, AllowN) reads time exclusively through the injected clock.Clock — both the cleanup ticker and the per-key bucket.lastRefill state advance only when the injected clock advances. FakeClock-driven tests can therefore exhaustively exercise burst/recovery behavior without sleeping.
ref: ADR docs/architecture/202605021500-adr-kernel-clock-injection.md (D6 PROD-CLOCK-INJECTION-01) — adapters/ratelimit replaced golang.org/x/time/rate.Limiter (which hard-codes time.Now() in its internal reserveN path) with this self-contained bucket so the D6 contract holds end-to-end at the rate-limit boundary.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Rate is the number of requests allowed per second per key. Default: 10.
Rate float64
// Burst is the maximum number of tokens that can be consumed in a single
// burst. Default: 20.
Burst int
// CleanupInterval is how often to scan for stale entries. Default: 1m.
CleanupInterval time.Duration
// StaleAfter is the idle duration after which a per-key limiter is removed.
// Default: 5m.
StaleAfter time.Duration
}
Config holds settings for the token bucket rate limiter.
type Limiter ¶
type Limiter struct {
// contains filtered or unexported fields
}
Limiter implements middleware.RateLimiter and middleware.WindowedRateLimiter using per-key token buckets with a self-contained token bucket algorithm.
func New ¶
New creates a per-IP token bucket rate limiter. It starts a background goroutine for stale entry cleanup. Call Close() to stop cleanup.
func (*Limiter) Close ¶
Close stops the background cleanup goroutine.
Close is non-blocking: close(l.stopCh) is O(1) and the refill goroutine will observe the signal at its next tick and exit. The ctx parameter is accepted for lifecycle.ContextCloser compatibility but not consumed because stopCh close is synchronous and cannot be short-circuited safely. Distinct from InMemoryEventBus.Close (which ignores ctx for similar reasons) and Subscriber.Close (which honors ctx to bound in-flight drain).
Close is idempotent: concurrent and repeated calls are safe.
ref: uber-go/fx app.go StopTimeout — ctx as shared shutdown budget. ref: uber-go/fx lifecycle OnStop(ctx) — ContextCloser pattern.