subjectlimiter

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: May 20, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package subjectlimiter caps in-flight HTTP requests per authenticated subject. A single runaway or compromised client identity cannot saturate the proxy's goroutine or upstream connection pool at the expense of every other caller.

Memory: entries are reclaimed by a pruner goroutine when a subject has been idle for IdleEvictAfter, so the map size stays proportional to ACTIVE principals, not the lifetime set of ever-seen subjects. sync.Map keeps the hot path lock-free except on first-seen subjects.

Correctness: each entry stamps lastUsed at construction time so a prune tick landing between LoadOrStore and the caller's first Add cannot evict a fresh entry (which would let a concurrent request create a second semaphore and effectively double the per-subject cap). Entries with in-flight work (inFlight > 0) are never evicted.

Index

Constants

View Source
const (
	// IdleEvictAfter is the window past which an entry with no
	// in-flight work is reclaimed by the pruner. 5 minutes covers the
	// longest realistic inter-request gap from a single MCP session
	// without letting orphaned entries linger forever.
	IdleEvictAfter = 5 * time.Minute
	// PruneInterval is the cadence at which the pruner goroutine scans
	// the map. Short enough to keep map size proportional to active
	// principals, long enough to keep the scan cheap.
	PruneInterval = 2 * time.Minute
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Limiter

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

Limiter caps concurrent requests per subject.

func New

func New(ctx context.Context, cap int64, logger *zap.Logger) *Limiter

New creates a Limiter and wires a pruner goroutine to ctx so it exits on process shutdown. Callers use the Middleware method as an http middleware.

func (*Limiter) Middleware

func (l *Limiter) Middleware(next http.Handler) http.Handler

Middleware returns an http.Handler wrapper that rejects the request with 503 + Retry-After when the per-subject cap would be exceeded. Must run AFTER the auth middleware that sets ContextSubject.

func (*Limiter) PruneOnce

func (l *Limiter) PruneOnce(now time.Time, idleAfter time.Duration)

PruneOnce performs a single prune pass. Exposed for tests; the production pruneLoop drives it on a ticker.

Jump to

Keyboard shortcuts

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