ratelimit

package
v0.1.18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 17, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package ratelimit provides adaptive concurrency control (AIMD) and a circuit breaker. The engine uses these to bound DB load and fail fast when the database is unhealthy. Implementations use only the standard library.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrKeyRate     = errors.New("ratelimit: the caller's request rate is exceeded")
	ErrKeyInflight = errors.New("ratelimit: the caller has too many requests in flight")
)

ErrKeyRate and ErrKeyInflight refuse a call past its key's own limits.

View Source
var ErrCircuitOpen = errors.New("ratelimit: circuit open")

ErrCircuitOpen is returned when the breaker is open.

View Source
var ErrRateLimited = errors.New("ratelimit: concurrency limit reached")

ErrRateLimited is returned when concurrency exceeds the current adaptive limit.

Functions

This section is empty.

Types

type Adaptive

type Adaptive struct {
	// contains filtered or unexported fields
}

Adaptive implements AIMD concurrency control: additive increase on success, multiplicative decrease on error or slow response. The limit moves between min and max in response to observed DB health. A decrease answers the results of requests sent before it as well: those come back after it without decreasing again, so one overload halves the limit once.

func NewAdaptive

func NewAdaptive(initial, min, max int64, rttThreshold time.Duration) *Adaptive

NewAdaptive returns an Adaptive limiter. initial is the starting concurrency limit; it moves within [min, max]. rttThreshold is the latency above which a response is considered "slow" and triggers a decrease.

func (*Adaptive) Acquire

func (a *Adaptive) Acquire() error

Acquire reserves a concurrency slot. It returns ErrRateLimited if the current concurrency is at the limit.

func (*Adaptive) Limit

func (a *Adaptive) Limit() int64

Limit returns the current concurrency limit (for introspection/testing).

func (*Adaptive) OnResult

func (a *Adaptive) OnResult(err error, d time.Duration)

OnResult adjusts the limit for a request that took d: multiplicative decrease on error or slow RTT, unless it was sent before the last decrease; additive increase otherwise.

func (*Adaptive) Release

func (a *Adaptive) Release()

Release frees a concurrency slot.

type Breaker

type Breaker struct {
	// contains filtered or unexported fields
}

Breaker is a circuit breaker: after threshold consecutive failures it opens for cooldown, then lets one probe through at a time (half-open) until a probe's result closes it, or reopens it.

func NewBreaker

func NewBreaker(threshold int64, cooldown time.Duration) *Breaker

NewBreaker returns a Breaker that opens after threshold consecutive failures, staying open for cooldown.

func (*Breaker) Allow

func (b *Breaker) Allow() (probe uint64, err error)

Allow returns ErrCircuitOpen if the breaker is open, or half-open with a probe already through. A request it lets through must end with Record, or with Release when its outcome says nothing of health; probe is nonzero for the half-open probe.

func (*Breaker) IsOpen

func (b *Breaker) IsOpen() bool

IsOpen reports whether the breaker is currently open.

func (*Breaker) Record

func (b *Breaker) Record(success bool)

Record counts a request's outcome. A success closes the breaker; a failure reopens a half-open one, and opens a closed one at threshold consecutive failures.

func (*Breaker) Release added in v0.1.13

func (b *Breaker) Release(probe uint64)

Release ends a request whose outcome says nothing of health (a cancelled one), probe as Allow returned it: the probe frees its place, and any other request (one let through before the breaker opened, an earlier probe) leaves the current probe's alone.

type KeyLimits added in v0.1.17

type KeyLimits struct {
	RPS         float64
	MaxInflight int
}

KeyLimits bound the calls of one key; zero is unlimited.

type Keyed added in v0.1.17

type Keyed struct {
	// contains filtered or unexported fields
}

Keyed bounds the calls of each key (a caller) by limits of its own: a rate and a number in flight, across the caller's sessions. Its state outlives configuration reloads: Update replaces the limits and keeps the state of the keys whose limits stay.

func NewKeyed added in v0.1.17

func NewKeyed() *Keyed

NewKeyed returns a Keyed without limits.

func (*Keyed) Acquire added in v0.1.17

func (k *Keyed) Acquire(key string) (release func(), err error)

Acquire admits a call of key, or refuses it with ErrKeyRate or ErrKeyInflight; release ends an admitted call.

func (*Keyed) Update added in v0.1.17

func (k *Keyed) Update(limits map[string]KeyLimits)

Update sets the limits of each key; keys not in limits are unlimited.

type TokenBucket

type TokenBucket struct {
	// contains filtered or unexported fields
}

TokenBucket is a bounded in-process request-rate limiter.

func NewTokenBucket

func NewTokenBucket(rate float64) *TokenBucket

NewTokenBucket returns nil when rate is non-positive.

func (*TokenBucket) Allow

func (b *TokenBucket) Allow() error

Allow consumes one token or returns ErrRateLimited.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL