ratelimit

package
v0.9.4 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package ratelimit is the domain layer for the RateLimit entity — a named rule set (requests / tokens / concurrency caps) attachable to a Policy, ProviderKey, or Model.

The Attachment type is also defined here because the entities that attach to a RateLimit depend on this package; reverse imports would create cycles.

store.go is the data-access layer for RateLimit. Mirrors the other entities.

Index

Constants

This section is empty.

Variables

AllMeters is the closed set as ordered data — the single source the OpenAPI shim reads to publish the `meter` enum. Pure domain values, no HTTP/openapi coupling here; keep it in sync with the const block above.

Functions

func PerModelScope

func PerModelScope(base, modelID string) string

PerModelScope adds the request model id to a bucket key so per-model rules partition correctly. Used when a Policy.RLBinding has non-empty Models (otherwise the binding is "any model" and gets one shared bucket). The modelID suffix lives in the key, not the namespace, so the Lua hash-tag boundary still groups all of a key's buckets.

func ResolveWithScope

func ResolveWithScope(namespace, subject string, rl *RateLimit) []pkgratelimit.Rule

ResolveWithScope is the policy-less variant used by proxy mode, where the rate-limit subject is not a Policy but a per-key hash or per-IP identifier. namespace identifies the bucket family ("proxy", "proxy-anon"); subject is the request's bucket key (relay-key hash, client IP, etc.). Key construction:

"{namespace}:{subject}:{rule-index}:{meter}"

Returns nil when rl is nil, disabled, or has no Rules.

Types

type Meter

type Meter string

Meter is the dimension a Rule counts.

const (
	MeterRequests               Meter = "requests"
	MeterConcurrency            Meter = "concurrency"
	MeterTokens                 Meter = "tokens"
	MeterTokensInput            Meter = "tokens.input"
	MeterTokensOutput           Meter = "tokens.output"
	MeterTokensCacheRead        Meter = "tokens.cache_read"
	MeterTokensCacheCreation    Meter = "tokens.cache_creation"
	MeterTokensReasoning        Meter = "tokens.reasoning"
	MeterTokensServerToolUseIn  Meter = "tokens.server_tool_use_input"
	MeterTokensServerToolUseOut Meter = "tokens.server_tool_use_output"
)

Closed set of recognised meters. Bare "tokens" sums every token sub-meter; "tokens.<key>" targets one. "concurrency" ignores Strategy.

type RateLimit

type RateLimit struct {
	Meta meta.Metadata `json:"metadata" yaml:"metadata"`
	Spec Spec          `json:"spec"     yaml:"spec"`
}

RateLimit is a named rule set. All three OwnerKinds are valid:

  • system: bundled, operator-immutable (e.g. inference-api, control-api).
  • provider: auto-injected upstream-tier mirror; Owner.ID = Provider id.
  • user: operator-defined.

func (*RateLimit) IsEnabled

func (r *RateLimit) IsEnabled() bool

IsEnabled returns true when Enabled is unset or explicitly true.

func (*RateLimit) Validate

func (r *RateLimit) Validate() error

Validate runs intra-row rules via the shared meta.Validator and enforces the RateLimit-specific owner shape:

  • Owner.Kind is required (any of system/provider/user).
  • Owner.Kind=provider requires Owner.ID (the Provider id).

Cross-entity checks (provider-owned RLs reference an existing Provider; system mirrors are unique per tier) live in the composition layer.

type Rule

type Rule struct {
	Meter    Meter    `` /* 228-byte string literal not displayed */
	Amount   int64    `json:"amount"   yaml:"amount"   validate:"required,gt=0"`
	Window   Window   `json:"window"   yaml:"window"   validate:"required,gt=0"`
	Strategy Strategy `` /* 126-byte string literal not displayed */
}

Rule is one cap. A RateLimit with N rules produces N concurrent buckets at request time. Strategy is per-rule — there is no spec-level default fallback.

Window is the measurement period, expressed on the wire (control-API JSON and stored JSONB) as an integer number of seconds — see the Window type.

type Spec

type Spec struct {
	Rules   []Rule `json:"rules"             yaml:"rules"             validate:"required,min=1,dive"`
	Enabled *bool  `json:"enabled,omitempty" yaml:"enabled,omitempty"` // nil = true
}

Spec carries the rule list and an enable flag.

type Store

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

Store is the RateLimit data-access type.

func NewStore

func NewStore(q *gen.Queries) *Store

NewStore constructs a Store from an existing sqlc Queries handle.

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, id string) error

Delete removes a RateLimit by id.

func (*Store) Get

func (s *Store) Get(ctx context.Context, id string) (*RateLimit, error)

Get returns the RateLimit with the given id, or (nil, nil) if not found.

func (*Store) List

func (s *Store) List(ctx context.Context) ([]*RateLimit, error)

List returns every RateLimit row.

func (*Store) Upsert

func (s *Store) Upsert(ctx context.Context, rl *RateLimit) error

Upsert writes rl. Caller is responsible for stamping Meta.ID.

type Strategy

type Strategy string

Strategy is the algorithm used to enforce a Rule.

const (
	StrategyTokenBucket   Strategy = "token-bucket"
	StrategySlidingWindow Strategy = "sliding-window"
	StrategyFixedWindow   Strategy = "fixed-window"
	StrategyLeakyBucket   Strategy = "leaky-bucket"
	// StrategySessionWindow anchors on first request, runs for `window`,
	// then idles until the next request anchors a fresh window. Used for
	// session-quota patterns like Anthropic's 5-hour limit.
	StrategySessionWindow Strategy = "session-window"
)

type Window added in v0.1.0

type Window time.Duration

Window is a rate-limit measurement period. In memory it is a time.Duration so the limiter keeps its native unit, but it marshals to/from JSON as a whole number of SECONDS — the granularity rate windows are ever expressed in (sub-second windows are not a real case). This makes both the control-API body and the stored JSONB human-legible ("60" not "60000000000") instead of leaking nanoseconds.

func (Window) Duration added in v0.1.0

func (w Window) Duration() time.Duration

Duration returns the window as a time.Duration for the limiter.

func (Window) MarshalJSON added in v0.1.0

func (w Window) MarshalJSON() ([]byte, error)

func (*Window) UnmarshalJSON added in v0.1.0

func (w *Window) UnmarshalJSON(b []byte) error

Jump to

Keyboard shortcuts

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