Documentation
¶
Overview ¶
Package limited provides DynamoDB-based rate limiting
Package limited provides DynamoDB-based rate limiting ¶
Package limited provides DynamoDB-based rate limiting ¶
Package limited provides DynamoDB-based rate limiting
Index ¶
- type AtomicRateLimiter
- type Clock
- type Config
- type DynamoRateLimiter
- func (r *DynamoRateLimiter) CheckAndIncrement(ctx context.Context, key RateLimitKey) (*LimitDecision, error)
- func (r *DynamoRateLimiter) CheckLimit(ctx context.Context, key RateLimitKey) (*LimitDecision, error)
- func (r *DynamoRateLimiter) GetUsage(ctx context.Context, key RateLimitKey) (*UsageStats, error)
- func (r *DynamoRateLimiter) RecordRequest(ctx context.Context, key RateLimitKey) error
- func (r *DynamoRateLimiter) SetClock(clock Clock)
- type Error
- type ErrorType
- type FixedWindowStrategy
- func (s *FixedWindowStrategy) CalculateWindows(now time.Time) []TimeWindow
- func (s *FixedWindowStrategy) GetLimit(key RateLimitKey) int
- func (s *FixedWindowStrategy) SetIdentifierLimit(identifier string, limit int)
- func (s *FixedWindowStrategy) SetResourceLimit(resource string, limit int)
- func (s *FixedWindowStrategy) ShouldAllow(counts map[string]int, limit int) bool
- type Limit
- type LimitDecision
- type MultiWindowStrategy
- type RateLimitEntry
- type RateLimitKey
- type RateLimitStrategy
- type RateLimitWindow
- type RateLimiter
- type RealClock
- type SlidingWindowStrategy
- func (s *SlidingWindowStrategy) CalculateWindows(now time.Time) []TimeWindow
- func (s *SlidingWindowStrategy) GetLimit(key RateLimitKey) int
- func (s *SlidingWindowStrategy) SetIdentifierLimit(identifier string, limit int)
- func (s *SlidingWindowStrategy) SetResourceLimit(resource string, limit int)
- func (s *SlidingWindowStrategy) ShouldAllow(counts map[string]int, limit int) bool
- type TimeWindow
- type UsageStats
- type UsageWindow
- type WindowConfig
- type WindowLimit
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AtomicRateLimiter ¶
type AtomicRateLimiter interface {
RateLimiter
// CheckAndIncrement performs an atomic check and increment operation
// Returns the new count and whether the request is allowed
CheckAndIncrement(ctx context.Context, key RateLimitKey) (*LimitDecision, error)
}
AtomicRateLimiter extends RateLimiter with atomic check-and-increment support
type Config ¶
type Config struct {
// Default limits
DefaultRequestsPerHour int
DefaultRequestsPerMinute int
DefaultBurstCapacity int
// Feature flags
EnableBurstCapacity bool
EnableSoftLimits bool // Warn but don't block
FailOpen bool // Allow requests if rate limiter fails
// Storage settings
TableName string
ConsistentRead bool
TTLHours int
// Custom limits by identifier
IdentifierLimits map[string]Limit
// Custom limits by resource
ResourceLimits map[string]Limit
}
Config contains configuration for the rate limiter
type DynamoRateLimiter ¶
type DynamoRateLimiter struct {
// contains filtered or unexported fields
}
DynamoRateLimiter implements RateLimiter using DynamoDB via DynamORM
func NewDynamoRateLimiter ¶
func NewDynamoRateLimiter(db core.DB, config *Config, strategy RateLimitStrategy, logger *zap.Logger) *DynamoRateLimiter
NewDynamoRateLimiter creates a new DynamoDB-based rate limiter
func (*DynamoRateLimiter) CheckAndIncrement ¶
func (r *DynamoRateLimiter) CheckAndIncrement(ctx context.Context, key RateLimitKey) (*LimitDecision, error)
CheckAndIncrement performs an atomic check and increment operation
func (*DynamoRateLimiter) CheckLimit ¶
func (r *DynamoRateLimiter) CheckLimit(ctx context.Context, key RateLimitKey) (*LimitDecision, error)
CheckLimit checks if a request is allowed based on rate limits
func (*DynamoRateLimiter) GetUsage ¶
func (r *DynamoRateLimiter) GetUsage(ctx context.Context, key RateLimitKey) (*UsageStats, error)
GetUsage returns current usage statistics for a rate limit key
func (*DynamoRateLimiter) RecordRequest ¶
func (r *DynamoRateLimiter) RecordRequest(ctx context.Context, key RateLimitKey) error
RecordRequest records that a request was made using atomic increment
func (*DynamoRateLimiter) SetClock ¶
func (r *DynamoRateLimiter) SetClock(clock Clock)
SetClock sets the clock for testing
type Error ¶
Error represents a rate limiter error
type FixedWindowStrategy ¶
type FixedWindowStrategy struct {
WindowSize time.Duration
MaxRequests int
IdentifierLimits map[string]int // Identifier-specific overrides
ResourceLimits map[string]int // Resource-specific overrides
}
FixedWindowStrategy implements fixed window rate limiting
func NewFixedWindowStrategy ¶
func NewFixedWindowStrategy(windowSize time.Duration, maxRequests int) *FixedWindowStrategy
NewFixedWindowStrategy creates a new fixed window strategy
func (*FixedWindowStrategy) CalculateWindows ¶
func (s *FixedWindowStrategy) CalculateWindows(now time.Time) []TimeWindow
CalculateWindows returns the time windows to check for the current time
func (*FixedWindowStrategy) GetLimit ¶
func (s *FixedWindowStrategy) GetLimit(key RateLimitKey) int
GetLimit returns the limit for a given key
func (*FixedWindowStrategy) SetIdentifierLimit ¶
func (s *FixedWindowStrategy) SetIdentifierLimit(identifier string, limit int)
SetIdentifierLimit sets a limit override for a specific identifier
func (*FixedWindowStrategy) SetResourceLimit ¶
func (s *FixedWindowStrategy) SetResourceLimit(resource string, limit int)
SetResourceLimit sets a limit override for a specific resource
func (*FixedWindowStrategy) ShouldAllow ¶
func (s *FixedWindowStrategy) ShouldAllow(counts map[string]int, limit int) bool
ShouldAllow determines if a request should be allowed given current counts
type Limit ¶
type Limit struct {
RequestsPerHour int
RequestsPerMinute int
BurstCapacity int
CustomWindows map[string]WindowLimit // e.g., "5m": {Requests: 100}
}
Limit defines rate limits for a specific entity
type LimitDecision ¶
type LimitDecision struct {
// Allowed indicates whether the request is allowed
Allowed bool
// CurrentCount is the current number of requests in the window
CurrentCount int
// Limit is the maximum allowed requests
Limit int
// ResetsAt is when the current window resets
ResetsAt time.Time
// RetryAfter is set if request is not allowed, indicating when to retry
RetryAfter *time.Duration
}
LimitDecision represents the result of a rate limit check
type MultiWindowStrategy ¶
type MultiWindowStrategy struct {
Windows []WindowConfig
IdentifierLimits map[string][]WindowConfig // Identifier-specific overrides
ResourceLimits map[string][]WindowConfig // Resource-specific overrides
}
MultiWindowStrategy implements multiple window rate limiting (e.g., 100 requests per minute AND 1000 requests per hour)
func NewMultiWindowStrategy ¶
func NewMultiWindowStrategy(windows []WindowConfig) *MultiWindowStrategy
NewMultiWindowStrategy creates a new multi-window strategy
func (*MultiWindowStrategy) CalculateWindows ¶
func (s *MultiWindowStrategy) CalculateWindows(now time.Time) []TimeWindow
CalculateWindows returns all windows to check
func (*MultiWindowStrategy) GetLimit ¶
func (s *MultiWindowStrategy) GetLimit(key RateLimitKey) int
GetLimit returns the limit for the first window (primary limit)
func (*MultiWindowStrategy) ShouldAllow ¶
func (s *MultiWindowStrategy) ShouldAllow(counts map[string]int, limit int) bool
ShouldAllow checks all windows
type RateLimitEntry ¶
type RateLimitEntry struct {
// PK/SK pattern for composite keys
PK string `dynamorm:"pk" json:"pk"` // {identifier}#{window_start}
SK string `dynamorm:"sk" json:"sk"` // {resource}#{operation}
Identifier string `json:"identifier"` // e.g., partner_id, user_id
Resource string `json:"resource"` // e.g., "api/v1/users"
Operation string `json:"operation"` // e.g., "GET", "POST"
// Window information
WindowStart int64 `json:"window_start"` // Unix timestamp
WindowType string `json:"window_type"` // "MINUTE", "HOUR", "CUSTOM"
WindowID string `json:"window_id"` // For query purposes
// Rate limit tracking
Count int64 `json:"count"` // Counter (atomic via UpdateBuilder)
// TTL for automatic cleanup
TTL int64 `dynamorm:"ttl" json:"ttl"` // Unix timestamp for expiration
// Metadata
CreatedAt time.Time `dynamorm:"created_at" json:"created_at"`
UpdatedAt time.Time `dynamorm:"updated_at" json:"updated_at"`
Metadata map[string]string `json:"metadata,omitempty"` // Additional context
}
RateLimitEntry tracks rate limit usage in DynamoDB
func (*RateLimitEntry) GetCompositeID ¶
func (r *RateLimitEntry) GetCompositeID() string
GetCompositeID returns a unique identifier for the rate limit entry
func (*RateLimitEntry) SetKeys ¶
func (r *RateLimitEntry) SetKeys()
SetKeys sets the PK and SK based on identifier, window_start, resource and operation
func (*RateLimitEntry) SetTTL ¶
func (r *RateLimitEntry) SetTTL(windowDuration time.Duration, bufferDuration time.Duration)
SetTTL sets the TTL based on window duration and buffer time
func (RateLimitEntry) TableName ¶
func (RateLimitEntry) TableName() string
TableName returns the table name for RateLimitEntry Can be overridden by setting LIMITED_TABLE_NAME environment variable
type RateLimitKey ¶
type RateLimitKey struct {
// Identifier is the primary identifier for the rate limit (e.g., partner_id, user_id, api_key)
Identifier string
// Resource identifies what resource is being accessed (e.g., "api/v1/users", "oauth/token")
Resource string
// Operation identifies the operation being performed (e.g., "GET", "POST", "READ", "WRITE")
Operation string
// Metadata provides additional context for the rate limit check
Metadata map[string]string
}
RateLimitKey identifies a unique rate limit bucket
type RateLimitStrategy ¶
type RateLimitStrategy interface {
// CalculateWindows returns the time windows to check for the current time
CalculateWindows(now time.Time) []TimeWindow
// GetLimit returns the limit for a given key
GetLimit(key RateLimitKey) int
// ShouldAllow determines if a request should be allowed given current counts
ShouldAllow(counts map[string]int, limit int) bool
}
RateLimitStrategy defines how rate limits are calculated
type RateLimitWindow ¶
type RateLimitWindow struct {
WindowType string // "MINUTE", "HOUR", "CUSTOM_<duration>"
Start time.Time
End time.Time
}
RateLimitWindow represents a time window for rate limiting
func GetDayWindow ¶
func GetDayWindow(now time.Time) RateLimitWindow
GetDayWindow returns the current day window
func GetFixedWindow ¶
func GetFixedWindow(now time.Time, duration time.Duration) RateLimitWindow
GetFixedWindow returns a fixed time window
func GetHourWindow ¶
func GetHourWindow(now time.Time) RateLimitWindow
GetHourWindow returns the current hour window
func GetMinuteWindow ¶
func GetMinuteWindow(now time.Time) RateLimitWindow
GetMinuteWindow returns the current minute window
type RateLimiter ¶
type RateLimiter interface {
// CheckLimit checks if a request is allowed based on rate limits
CheckLimit(ctx context.Context, key RateLimitKey) (*LimitDecision, error)
// RecordRequest records that a request was made (should be called after CheckLimit)
RecordRequest(ctx context.Context, key RateLimitKey) error
// GetUsage returns current usage statistics for a rate limit key
GetUsage(ctx context.Context, key RateLimitKey) (*UsageStats, error)
}
RateLimiter defines the interface for rate limiting implementations
type SlidingWindowStrategy ¶
type SlidingWindowStrategy struct {
WindowSize time.Duration
MaxRequests int
Granularity time.Duration // How fine-grained the sliding window is (e.g., 1 minute)
IdentifierLimits map[string]int // Identifier-specific overrides
ResourceLimits map[string]int // Resource-specific overrides
}
SlidingWindowStrategy implements sliding window rate limiting
func NewSlidingWindowStrategy ¶
func NewSlidingWindowStrategy(windowSize time.Duration, maxRequests int, granularity time.Duration) *SlidingWindowStrategy
NewSlidingWindowStrategy creates a new sliding window strategy
func (*SlidingWindowStrategy) CalculateWindows ¶
func (s *SlidingWindowStrategy) CalculateWindows(now time.Time) []TimeWindow
CalculateWindows returns the time windows to check for sliding window
func (*SlidingWindowStrategy) GetLimit ¶
func (s *SlidingWindowStrategy) GetLimit(key RateLimitKey) int
GetLimit returns the limit for a given key
func (*SlidingWindowStrategy) SetIdentifierLimit ¶
func (s *SlidingWindowStrategy) SetIdentifierLimit(identifier string, limit int)
SetIdentifierLimit sets a limit override for a specific identifier
func (*SlidingWindowStrategy) SetResourceLimit ¶
func (s *SlidingWindowStrategy) SetResourceLimit(resource string, limit int)
SetResourceLimit sets a limit override for a specific resource
func (*SlidingWindowStrategy) ShouldAllow ¶
func (s *SlidingWindowStrategy) ShouldAllow(counts map[string]int, limit int) bool
ShouldAllow determines if a request should be allowed given current counts
type TimeWindow ¶
type TimeWindow struct {
Start time.Time
End time.Time
Key string // Used for storage key generation
}
TimeWindow represents a time period for rate limiting
type UsageStats ¶
type UsageStats struct {
Identifier string
Resource string
CurrentHour UsageWindow
CurrentMinute UsageWindow
DailyTotal int
CustomWindows map[string]UsageWindow // For custom window sizes
}
UsageStats provides detailed usage information
type UsageWindow ¶
UsageWindow represents usage within a time window
type WindowConfig ¶
WindowConfig defines a single window configuration
type WindowLimit ¶
WindowLimit defines limits for a custom time window