ratelimit

package
v2.4.19 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package ratelimit provides the shared provider rate budget: a reusable token-bucket limiter generalized from the rerank pacer (PR #138) so every subsystem that dials the same provider base URL (rerank, embedding, agent chat) draws from one bucket instead of competing for the same key without coordination.

The limiter is a classic token bucket: tokens accrue at the provider rate (rpm/60 per second) up to the per-minute budget as burst capacity, and every Wait consumes one token. The lock only guards bucket bookkeeping — callers NEVER hold it while sleeping:

  • callers within budget (a token is available) proceed immediately, so independent concurrent requests are never serialized;
  • excess callers reserve a future refill slot by letting the balance go negative and then concurrently sleep only their own computed delay; no caller waits behind another caller's sleep;
  • the provider rate is respected globally: emissions are spaced by the refill rate and instantaneous burst is bounded by the accrued budget.

now and sleep are injectable so tests never wait on wall time.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NormalizeProviderKey

func NormalizeProviderKey(raw string) string

NormalizeProviderKey collapses the base-URL spellings of one provider to a single registry key: scheme and host are case-insensitive, a trailing slash is insignificant, and an unparseable value degrades to the trimmed lowercase literal so budgeting never panics on operator input.

Types

type Limiter

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

Limiter paces one shared provider budget in requests per minute. A Limiter with rpm <= 0 is an unlimited passthrough: Wait returns immediately and no bookkeeping happens (the documented default when CORTEX_PROVIDER_RPM is unset, preserving current behavior).

func New

func New(rpm int, opts ...Option) *Limiter

New builds a limiter for the shared provider budget expressed in requests per minute. rpm <= 0 yields an unlimited limiter.

func (*Limiter) RPM

func (l *Limiter) RPM() int

RPM reports the configured requests-per-minute budget (0 = unlimited).

func (*Limiter) Wait

func (l *Limiter) Wait()

Wait consumes one token from the bucket, blocking only until the reserved refill token exists. It never fails and never holds the lock while sleeping, so concurrent callers pace independently.

type Option

type Option func(*Limiter)

Option customizes a Limiter. The clock and sleep options exist so tests never wait on wall time; production composition uses the defaults.

func WithClock

func WithClock(now func() time.Time) Option

WithClock overrides the time source.

func WithSleep

func WithSleep(sleep func(time.Duration)) Option

WithSleep overrides the wait primitive.

type Registry

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

Registry holds one shared budget per normalized provider base URL, so all server subsystems dialing the same provider draw from the same bucket. A nil Registry, or a Registry built with rpm <= 0, hands out nil budgets and every consumer falls back to its local default behavior.

func NewRegistry

func NewRegistry(rpm int, opts ...Option) *Registry

NewRegistry builds the server-wide provider budget registry. rpm <= 0 means unlimited: For always returns nil and consumers keep current behavior.

func (*Registry) For

func (r *Registry) For(baseURL string) *Limiter

For returns the shared limiter for the provider behind baseURL, creating it on first use. A nil receiver returns nil (unlimited).

func (*Registry) RPM

func (r *Registry) RPM() int

RPM reports the registry-wide requests-per-minute budget (0 = unlimited).

Jump to

Keyboard shortcuts

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