Documentation
¶
Overview ¶
Package ratelimit provides local rate-limiting primitives: a token bucket, a leaky bucket, and a concurrency limiter. They are transport-agnostic and can be composed into middleware or applied directly.
Index ¶
Constants ¶
const ( // Unknown indicates the outcome could not be determined (store error). Unknown = iota // Allowed means the request is within quota and quota is not yet full. Allowed // HitQuota means the request is within quota and just filled it. HitQuota // OverQuota means the request exceeds the quota. OverQuota )
PeriodLimit result codes. Unlike a boolean limiter, these let callers distinguish "allowed", "allowed but just hit the quota", and "rejected".
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ConcurrencyLimiter ¶
type ConcurrencyLimiter struct {
// contains filtered or unexported fields
}
ConcurrencyLimiter limits the number of concurrently active operations. Unlike TokenBucket/LeakyBucket it is not time-based: the caller must explicitly release an acquired slot.
func NewConcurrencyLimiter ¶
func NewConcurrencyLimiter(n int) *ConcurrencyLimiter
NewConcurrencyLimiter returns a ConcurrencyLimiter allowing n concurrent operations.
func (*ConcurrencyLimiter) Acquire ¶
func (l *ConcurrencyLimiter) Acquire() bool
Acquire attempts to take a slot without blocking. It returns false when the concurrency limit is reached.
func (*ConcurrencyLimiter) Release ¶
func (l *ConcurrencyLimiter) Release()
Release returns a previously acquired slot.
type LeakyBucket ¶
type LeakyBucket struct {
// contains filtered or unexported fields
}
LeakyBucket is a leaky-bucket rate limiter: requests fill a bucket of fixed capacity that leaks one request per interval.
func NewLeakyBucket ¶
func NewLeakyBucket(capacity int, interval time.Duration) *LeakyBucket
NewLeakyBucket returns a LeakyBucket that holds up to capacity requests and leaks one request per interval.
type Limiter ¶
type Limiter interface {
// Allow reports whether a single request may proceed.
Allow() bool
}
Limiter decides whether a request may proceed.
type PeriodLimit ¶
type PeriodLimit struct {
// contains filtered or unexported fields
}
PeriodLimit limits how many requests are allowed within a rolling (or aligned) time window, backed by a shared Store for cross-instance coordination.
func NewPeriodLimit ¶
func NewPeriodLimit(period time.Duration, quota int, store Store, keyPrefix string, opts ...PeriodOption) *PeriodLimit
NewPeriodLimit returns a PeriodLimit allowing quota requests per period, keyed under keyPrefix.
type PeriodOption ¶
type PeriodOption func(*PeriodLimit)
PeriodOption customizes a PeriodLimit.
func Align ¶
func Align() PeriodOption
Align aligns the window to natural boundaries (e.g. a 1-day period resets at midnight rather than one day after first use).
type RateLimiter ¶
type RateLimiter interface {
// Acquire reports whether a request may proceed, consuming a token if so.
Acquire(ctx context.Context) bool
// Status reports the current (max, cur, interval) limiter state.
Status(ctx context.Context) (max, cur int, interval time.Duration)
}
RateLimiter is a lightweight, local (non-distributed) rate limiter for non-critical paths where a Redis round-trip would be too heavy.
func NewQPSLimiter ¶
func NewQPSLimiter(interval time.Duration, limit int) RateLimiter
NewQPSLimiter returns a local QPS limiter that refills to limit tokens every interval. The returned RateLimiter owns a background goroutine released when the limiter is garbage collected via the finalizer-free Stop-free design: callers using it for the process lifetime need no explicit shutdown.
func NewQPSLimiterWithStop ¶
func NewQPSLimiterWithStop(interval time.Duration, limit int) (RateLimiter, func())
NewQPSLimiterWithStop returns a QPS limiter together with a stop function that releases its background goroutine.
type Store ¶
type Store interface {
// TakeTokens atomically consumes n tokens from the bucket identified by key,
// which refills at rate tokens per second up to burst capacity. It reports
// whether the tokens were granted.
TakeTokens(ctx context.Context, key string, rate, burst, n int) (bool, error)
// IncrWindow atomically increments the counter identified by key and returns
// the new value. The first increment starts an expiry of window.
IncrWindow(ctx context.Context, key string, window time.Duration) (int64, error)
// Ping checks the health of the backing store.
Ping(ctx context.Context) error
// Close releases resources held by the store.
Close() error
}
Store is the storage abstraction for distributed rate limiting. Implementations provide atomic operations across instances; a memory implementation is used for single-instance or testing, and a Redis implementation for multi-instance coordination. It is defined consumer-side (interface segregation) so callers do not depend on any specific backend.
type TokenBucket ¶
type TokenBucket struct {
// contains filtered or unexported fields
}
TokenBucket is a token-bucket rate limiter: it refills tokens at a steady rate and allows bursts up to the configured capacity.
func NewTokenBucket ¶
func NewTokenBucket(rate float64, burst int) *TokenBucket
NewTokenBucket returns a TokenBucket refilling rate tokens per second and allowing bursts of up to burst tokens.
type TokenLimiter ¶
type TokenLimiter struct {
// contains filtered or unexported fields
}
TokenLimiter is a distributed token-bucket limiter with a local fallback: it normally consumes tokens from a shared Store, but when the store becomes unavailable it transparently degrades to an in-process limiter and resumes the store once it recovers. This prevents a remote-store outage from taking rate limiting down with it (cascading-failure protection).
func NewTokenLimiter ¶
func NewTokenLimiter(rate, burst int, store Store, key string) *TokenLimiter
NewTokenLimiter returns a TokenLimiter consuming from store under key, refilling at rate tokens per second with bursts up to burst.
func (*TokenLimiter) Allow ¶
func (l *TokenLimiter) Allow() bool
Allow reports whether a single request may proceed.
func (*TokenLimiter) AllowContext ¶
func (l *TokenLimiter) AllowContext(ctx context.Context, n int) bool
AllowContext reports whether n requests may proceed, honoring ctx for the remote store call so a canceled request does not block on the store.
func (*TokenLimiter) AllowN ¶
func (l *TokenLimiter) AllowN(n int) bool
AllowN reports whether n requests may proceed.
func (*TokenLimiter) Close ¶
func (l *TokenLimiter) Close() error
Close stops the recovery monitor goroutine, if any. It is idempotent and safe to call when the limiter is no longer needed.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
store
|
|
|
memory
Package memory provides an in-process ratelimit.Store.
|
Package memory provides an in-process ratelimit.Store. |
|
redis
Package redis provides a Redis-backed ratelimit.Store using atomic Lua scripts, for distributed rate limiting across multiple instances.
|
Package redis provides a Redis-backed ratelimit.Store using atomic Lua scripts, for distributed rate limiting across multiple instances. |