Documentation
¶
Index ¶
- type Debug
- func (d Debug[TInput, TKey]) Allowed() bool
- func (d Debug[TInput, TKey]) ExecutionTime() time.Time
- func (d Debug[TInput, TKey]) Input() TInput
- func (d Debug[TInput, TKey]) Key() TKey
- func (d Debug[TInput, TKey]) Limit() Limit
- func (d Debug[TInput, TKey]) RetryAfter() time.Duration
- func (d Debug[TInput, TKey]) TokensConsumed() int64
- func (d Debug[TInput, TKey]) TokensRemaining() int64
- func (d Debug[TInput, TKey]) TokensRequested() int64
- type Details
- func (d Details[TInput, TKey]) Allowed() bool
- func (d Details[TInput, TKey]) ExecutionTime() time.Time
- func (d Details[TInput, TKey]) RetryAfter() time.Duration
- func (d Details[TInput, TKey]) TokensConsumed() int64
- func (d Details[TInput, TKey]) TokensRemaining() int64
- func (d Details[TInput, TKey]) TokensRequested() int64
- type KeyFunc
- type Limit
- type LimitFunc
- type Limiter
- func (r *Limiter[TInput, TKey]) Allow(input TInput) bool
- func (r *Limiter[TInput, TKey]) AllowN(input TInput, n int64) bool
- func (r *Limiter[TInput, TKey]) AllowNWithDebug(input TInput, n int64) (bool, []Debug[TInput, TKey])
- func (r *Limiter[TInput, TKey]) AllowNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
- func (r *Limiter[TInput, TKey]) AllowWithDebug(input TInput) (bool, []Debug[TInput, TKey])
- func (r *Limiter[TInput, TKey]) AllowWithDetails(input TInput) (bool, Details[TInput, TKey])
- func (r *Limiter[TInput, TKey]) Peek(input TInput) bool
- func (r *Limiter[TInput, TKey]) PeekN(input TInput, n int64) bool
- func (r *Limiter[TInput, TKey]) PeekNWithDebug(input TInput, n int64) (bool, []Debug[TInput, TKey])
- func (r *Limiter[TInput, TKey]) PeekNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
- func (r *Limiter[TInput, TKey]) PeekWithDebug(input TInput) (bool, []Debug[TInput, TKey])
- func (r *Limiter[TInput, TKey]) PeekWithDetails(input TInput) (bool, Details[TInput, TKey])
- func (r *Limiter[TInput, TKey]) Wait(ctx context.Context, input TInput) bool
- func (r *Limiter[TInput, TKey]) WaitN(ctx context.Context, input TInput, n int64) bool
- type Limiters
- func (rs *Limiters[TInput, TKey]) Allow(input TInput) bool
- func (rs *Limiters[TInput, TKey]) AllowN(input TInput, n int64) bool
- func (rs *Limiters[TInput, TKey]) AllowNWithDebug(input TInput, n int64) (bool, []Debug[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) AllowNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) AllowWithDebug(input TInput) (bool, []Debug[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) AllowWithDetails(input TInput) (bool, Details[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) Peek(input TInput) bool
- func (rs *Limiters[TInput, TKey]) PeekN(input TInput, n int64) bool
- func (rs *Limiters[TInput, TKey]) PeekNWithDebug(input TInput, n int64) (bool, []Debug[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) PeekNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) PeekWithDebug(input TInput) (bool, []Debug[TInput, TKey])
- func (rs *Limiters[TInput, TKey]) PeekWithDetails(input TInput) (bool, Details[TInput, TKey])
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Debug ¶ added in v0.2.0
type Debug[TInput any, TKey comparable] struct { // contains filtered or unexported fields }
Debug is a struct that contains the details of a rate limit check for a single bucket. Used by debug APIs that return per-bucket information.
func (Debug[TInput, TKey]) Allowed ¶ added in v0.2.0
Allowed returns true if the request was allowed.
func (Debug[TInput, TKey]) ExecutionTime ¶ added in v0.2.0
ExecutionTime returns the time the request was executed.
func (Debug[TInput, TKey]) Input ¶ added in v0.2.0
func (d Debug[TInput, TKey]) Input() TInput
Input returns the input that was used to create the bucket.
func (Debug[TInput, TKey]) Key ¶ added in v0.2.0
func (d Debug[TInput, TKey]) Key() TKey
Key returns the key of the bucket that was used for the request.
func (Debug[TInput, TKey]) Limit ¶ added in v0.2.0
Limit returns the limit that was used for the request.
func (Debug[TInput, TKey]) RetryAfter ¶ added in v0.2.0
RetryAfter returns the duration after which the bucket may have refilled.
func (Debug[TInput, TKey]) TokensConsumed ¶ added in v0.2.0
TokensConsumed returns the number of tokens that were consumed for the request.
func (Debug[TInput, TKey]) TokensRemaining ¶ added in v0.2.0
TokensRemaining returns the number of remaining tokens in the bucket
func (Debug[TInput, TKey]) TokensRequested ¶ added in v0.2.0
TokensRequested returns the number of tokens that were requested for the request.
type Details ¶
type Details[TInput any, TKey comparable] struct { // contains filtered or unexported fields }
Details contains aggregated rate limit details across multiple buckets/limits, optimized for the common use case of setting response headers without expensive allocations.
func (Details[TInput, TKey]) ExecutionTime ¶
ExecutionTime returns the time the request was executed.
func (Details[TInput, TKey]) RetryAfter ¶
RetryAfter returns the duration after which all relevant buckets may have refilled.
func (Details[TInput, TKey]) TokensConsumed ¶
TokensConsumed returns the number of tokens that were consumed for the request.
func (Details[TInput, TKey]) TokensRemaining ¶
TokensRemaining returns the minimum number of remaining tokens across all buckets. This represents "after using this many tokens, you will be denied".
func (Details[TInput, TKey]) TokensRequested ¶
TokensRequested returns the number of tokens that were requested for the request.
type KeyFunc ¶ added in v0.2.0
type KeyFunc[TInput any, TKey comparable] func(input TInput) TKey
KeyFunc is a function that takes an input and returns a bucket key.
type Limit ¶
type Limit struct {
// contains filtered or unexported fields
}
func NewLimit ¶
NewLimit creates a new rate with the given count and period. For example, to create a rate of 10 requests per second, use:
limit := rate.NewLimit(10, time.Second)
func (Limit) DurationPerToken ¶
type Limiter ¶
type Limiter[TInput any, TKey comparable] struct { // contains filtered or unexported fields }
Limiter is a rate limiter that can be used to limit the rate of requests to a given key.
func NewLimiter ¶
func NewLimiter[TInput any, TKey comparable](keyFunc KeyFunc[TInput, TKey], limits ...Limit) *Limiter[TInput, TKey]
NewLimiter creates a new rate limiter
func NewLimiterFunc ¶
func NewLimiterFunc[TInput any, TKey comparable](keyFunc KeyFunc[TInput, TKey], limitFuncs ...LimitFunc[TInput]) *Limiter[TInput, TKey]
NewLimiterFunc creates a new rate limiter with a dynamic limit function. Use this if you wish to apply a different limit based on the input, for example by URL path. The LimitFunc takes the same input type as the Keyer function.
func (*Limiter[TInput, TKey]) Allow ¶
Allow returns true if one or more tokens are available for the given key. If true, it will consume a token from the key's bucket. If false, no token will be consumed.
If the Limiter has multiple limits, Allow will return true only if all limits allow the request, and one token will be consumed against each limit. If any limit would be exceeded, no token will be consumed against any limit.
func (*Limiter[TInput, TKey]) AllowN ¶
AllowN returns true if at least `n` tokens are available for the given key. If true, it will consume `n` tokens. If false, no token will be consumed.
If the Limiter has multiple limits, AllowN will return true only if all limits allow the request, and `n` tokens will be consumed against each limit. If any limit would be exceeded, no token will be consumed against any limit.
func (*Limiter[TInput, TKey]) AllowNWithDebug ¶
func (r *Limiter[TInput, TKey]) AllowNWithDebug(input TInput, n int64) (bool, []Debug[TInput, TKey])
AllowNWithDebug returns true if at least `n` tokens are available for the given key, along with detailed debugging information about all bucket(s), remaining tokens, etc. You might use these details for logging, debugging, etc.
Note: This method allocates and may be expensive for performance-critical paths. For setting response headers, consider using AllowNWithDetails instead.
If true, it will consume `n` tokens. If false, no token will be consumed.
If the Limiter has multiple limits, AllowNWithDebug will return true only if all limits allow the request, and `n` tokens will be consumed against each limit. If any limit would be exceeded, no token will be consumed against any limit.
func (*Limiter[TInput, TKey]) AllowNWithDetails ¶
func (r *Limiter[TInput, TKey]) AllowNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
AllowNWithDetails returns true if at least `n` tokens are available for the given key, along with details for setting response headers.
If true, it will consume `n` tokens. If false, no token will be consumed.
If the Limiter has multiple limits, AllowNWithDetails will return true only if all limits allow the request, and `n` tokens will be consumed against each limit. If any limit would be exceeded, no token will be consumed against any limit.
func (*Limiter[TInput, TKey]) AllowWithDebug ¶
AllowWithDebug returns true if a token is available for the given key, along with detailed debugging information about all bucket(s) and tokens. You might use these details for logging, debugging, etc.
Note: This method allocates and may be expensive for performance-critical paths. For setting response headers, consider using AllowWithDetails instead.
If true, it will consume one token. If false, no token will be consumed.
If the Limiter has multiple limits, AllowWithDebug will return true only if all limits allow the request, and one token will be consumed against each limit. If any limit would be exceeded, no token will be consumed against any limit.
func (*Limiter[TInput, TKey]) AllowWithDetails ¶
AllowWithDetails returns true if a token is available for the given key, along with details for setting response headers.
If true, it will consume one token. If false, no token will be consumed.
If the Limiter has multiple limits, AllowWithDetails will return true only if all limits allow the request, and one token will be consumed against each limit. If any limit would be exceeded, no token will be consumed against any limit.
func (*Limiter[TInput, TKey]) Peek ¶
Peek returns true if tokens are available for the given key, but without consuming any tokens.
func (*Limiter[TInput, TKey]) PeekN ¶
PeekN returns true if tokens are available for the given key, but without consuming any tokens.
func (*Limiter[TInput, TKey]) PeekNWithDebug ¶
PeekNWithDebug returns true if `n` tokens are available for the given key, along with detailed debugging information about all bucket(s) and remaining tokens. You might use these details for logging, debugging, etc.
Note: This method allocates and may be expensive for performance-critical paths. For setting response headers, consider using PeekNWithDetails instead.
No tokens are consumed.
func (*Limiter[TInput, TKey]) PeekNWithDetails ¶
func (r *Limiter[TInput, TKey]) PeekNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
PeekNWithDetails returns true if `n` tokens are available for the given key, along with aggregated details optimized for setting response headers. This method avoids allocations and is suitable for performance-critical paths.
No tokens are consumed.
func (*Limiter[TInput, TKey]) PeekWithDebug ¶
PeekWithDebug returns true if tokens are available for the given key, and detailed debugging information about all bucket(s) and the execution time. You might use these details for logging, debugging, etc.
Note: This method allocates and may be expensive for performance-critical paths. For setting response headers, consider using PeekWithDetails instead.
No tokens are consumed.
func (*Limiter[TInput, TKey]) PeekWithDetails ¶
PeekWithDetails returns true if tokens are available for the given key, along with aggregated details optimized for setting response headers. This method avoids allocations and is suitable for performance-critical paths.
No tokens are consumed.
func (*Limiter[TInput, TKey]) Wait ¶
Wait will poll [Allow] for a period of time, until it is cancelled by the passed context. It has the effect of adding latency to requests instead of refusing them immediately. Consider it graceful degradation.
Wait will return true if a token becomes available prior to the context cancellation, and will consume a token. It will return false if not, and therefore not consume a token.
Take care to create an appropriate context. You almost certainly want context.WithTimeout or context.WithDeadline.
You should be conservative, as Wait will introduce backpressure on your upstream systems -- connections may be held open longer, requests may queue in memory.
A good starting place will be to timeout after waiting for one token. For example:
ctx := context.WithTimeout(ctx, limit.DurationPerToken())
Wait offers best-effort FIFO ordering of requests. Under sustained contention (when multiple requests wait longer than ~1ms), the Go runtime's mutex starvation mode ensures strict FIFO ordering. Under light load, ordering may be less strict but performance is optimized.
func (*Limiter[TInput, TKey]) WaitN ¶
WaitN will poll Limiter.AllowN for a period of time, until it is cancelled by the passed context. It has the effect of adding latency to requests instead of refusing them immediately. Consider it graceful degradation.
WaitN will return true if `n` tokens become available prior to the context cancellation, and will consume `n` tokens. If not, it will return false, and therefore consume no tokens.
Take care to create an appropriate context. You almost certainly want context.WithTimeout or context.WithDeadline.
You should be conservative, as Wait will introduce backpressure on your upstream systems -- connections may be held open longer, requests may queue in memory.
A good starting place will be to timeout after waiting for one token. For example:
ctx := context.WithTimeout(ctx, limit.DurationPerToken())
WaitN offers best-effort FIFO ordering of requests. Under sustained contention (when multiple requests wait longer than ~1ms), the Go runtime's mutex starvation mode ensures strict FIFO ordering. Under light load, ordering may be less strict but performance is optimized.
type Limiters ¶ added in v0.2.0
type Limiters[TInput any, TKey comparable] struct { // contains filtered or unexported fields }
Limiters is a collection of Limiter.
func Combine ¶ added in v0.2.0
func Combine[TInput any, TKey comparable](limiters ...*Limiter[TInput, TKey]) *Limiters[TInput, TKey]
Combine combines multiple Limiter into a single Limiters, which can be treated like a single with Allow, etc.
func (*Limiters[TInput, TKey]) AllowNWithDebug ¶ added in v0.2.0
func (*Limiters[TInput, TKey]) AllowNWithDetails ¶ added in v0.2.0
func (*Limiters[TInput, TKey]) AllowWithDebug ¶ added in v0.2.0
func (*Limiters[TInput, TKey]) AllowWithDetails ¶ added in v0.2.0
func (*Limiters[TInput, TKey]) Peek ¶ added in v0.2.0
Peek returns true if tokens are available for the given input across all limiters, but without consuming any tokens.
func (*Limiters[TInput, TKey]) PeekN ¶ added in v0.2.0
PeekN returns true if `n` tokens are available for the given input across all limiters, but without consuming any tokens.
func (*Limiters[TInput, TKey]) PeekNWithDebug ¶ added in v0.2.0
func (rs *Limiters[TInput, TKey]) PeekNWithDebug(input TInput, n int64) (bool, []Debug[TInput, TKey])
PeekNWithDebug returns true if `n` tokens are available for the given input across all limiters, along with detailed debugging information about all bucket(s) and remaining tokens. You might use these details for logging, debugging, etc.
Note: This method allocates and may be expensive for performance-critical paths. For setting response headers, consider using PeekNWithDetails instead.
No tokens are consumed.
func (*Limiters[TInput, TKey]) PeekNWithDetails ¶ added in v0.2.0
func (rs *Limiters[TInput, TKey]) PeekNWithDetails(input TInput, n int64) (bool, Details[TInput, TKey])
PeekNWithDetails returns true if `n` tokens are available for the given input across all limiters, along with aggregated details optimized for setting response headers. This method avoids allocations and is suitable for performance-critical paths.
No tokens are consumed.
func (*Limiters[TInput, TKey]) PeekWithDebug ¶ added in v0.2.0
PeekWithDebug returns true if tokens are available for the given input across all limiters, along with detailed debugging information about all bucket(s) and the execution time. You might use these details for logging, debugging, etc.
Note: This method allocates and may be expensive for performance-critical paths. For setting response headers, consider using PeekWithDetails instead.
No tokens are consumed.
func (*Limiters[TInput, TKey]) PeekWithDetails ¶ added in v0.2.0
PeekWithDetails returns true if tokens are available for the given input across all limiters, along with aggregated details optimized for setting response headers. This method avoids allocations and is suitable for performance-critical paths.
No tokens are consumed.