resilience

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package resilience provides circuit breaker, rate limiting, and query timeout utilities.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CircuitBreakerMiddleware

func CircuitBreakerMiddleware(cb *gobreaker.CircuitBreaker) func(http.Handler) http.Handler

CircuitBreakerMiddleware wraps a handler with a gobreaker circuit breaker. When the circuit is open it returns 503 with Retry-After: 8. Failures are counted when the handler writes a 5xx response.

func IsOpen

func IsOpen(cb *gobreaker.CircuitBreaker) bool

IsOpen is the hot-path state check — an O(1) mutex read with zero allocations. Call this before executing a query to decide whether to serve from cache or return 503.

func NewQueryBreaker

func NewQueryBreaker(name string) *gobreaker.CircuitBreaker

NewQueryBreaker returns a circuit breaker tuned for PostgreSQL query protection.

Opens when ≥10 requests have a ≥60% failure rate. Transitions open→half-open after 8 s; allows 2 probe requests in half-open.

func RateLimit

func RateLimit(tl *TenantLimiter) func(http.Handler) http.Handler

RateLimit enforces a configured TenantLimiter's per-tenant policy. It is the tier-less entry point used by the server: the limiter already carries its RPS/Burst config, so the tier argument is irrelevant and passed as TierPro.

func RateLimitMiddleware

func RateLimitMiddleware(tl *TenantLimiter, tier Tier) func(http.Handler) http.Handler

RateLimitMiddleware returns a chi-compatible middleware that enforces per-tenant rate limits. Tenants not found in context are skipped (e.g., health checks). Returns 429 Too Many Requests when the token bucket is empty.

func WithQueryTimeout

func WithQueryTimeout(ctx context.Context, fn func(ctx context.Context) error) error

WithQueryTimeout executes fn with a 250 ms deadline. On a single DeadlineExceeded it retries once after 100 ms backoff. All other errors are returned immediately without retry.

Types

type RateLimitConfig

type RateLimitConfig struct {
	RPS   float64 // sustained requests per second, per tenant
	Burst int     // bucket capacity for short spikes
}

RateLimitConfig sets an explicit per-tenant token-bucket policy, independent of subscription tier. Used to wire the limiter from environment configuration.

type TenantLimiter

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

TenantLimiter provides per-tenant token-bucket rate limiting. Each tenant gets an independent limiter keyed by tenantID. With a nil cfg the burst size equals the tier rate (1-second burst capacity); with cfg set, every tenant uses cfg.RPS / cfg.Burst and the tier is ignored.

Past maxLimiters distinct tenants, additional (unknown) tenants share a single overflow bucket: memory stays bounded and the rate limit still applies.

func NewConfiguredLimiter

func NewConfiguredLimiter(cfg RateLimitConfig) *TenantLimiter

NewConfiguredLimiter creates a TenantLimiter that applies cfg to every tenant.

func NewTenantLimiter

func NewTenantLimiter() *TenantLimiter

NewTenantLimiter creates an empty tier-based TenantLimiter.

func (*TenantLimiter) Allow

func (tl *TenantLimiter) Allow(tenantID string, tier Tier) bool

Allow reports whether tenantID may send another request under tier constraints. A new limiter is lazily created on first access for each tenantID.

type Tier

type Tier string

Tier is a subscription plan that determines the allowed request rate.

const (
	TierFree Tier = "free" // 100 req/s
	TierPro  Tier = "pro"  // 1000 req/s
)

Jump to

Keyboard shortcuts

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