backoff

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type KeyedLimiter

type KeyedLimiter interface {
	Allow(ctx context.Context, key string) (ok bool, wait time.Duration, err error)
	Reset(ctx context.Context, key string) error
}

type Limiter

type Limiter interface {
	Allow(ctx context.Context) (ok bool, wait time.Duration, err error)
	Reset(ctx context.Context) error
}

type LimiterOpts

type LimiterOpts struct {
	// BaseWait is the initial delay used for the first back-off, which
	// then gets increased by GrowthFactor as the backoff escalates.
	//
	// Must be less than or equal to MaxWait.
	//
	// Defaults to 1s
	BaseWait time.Duration

	// MaxWait caps the maximum duration a caller will ever be required to
	// wait.
	//
	// It allows for a long "memory" (via PenaltyDecayInterval) without completely
	// bricking a user's access, e.g. by sending them a 1-week wait time.
	//
	// Example: you could have a PenaltyDecayInterval of 48 * time.Hour,
	// and a MaxWait of 30 * time.Seconds. This would mean that an offender
	// that causes a burst of activity would quickly be limited to only
	// performing an action every 30s, and if they came back the next day,
	// the limit would still be in place.
	//
	// MaxWait cannot be greater than PenaltyDecayInterval, because this
	// would mean MaxWait could never be reached, as the penalty would decay
	// first.
	//
	// Defaults to PenaltyDecayInterval
	MaxWait time.Duration

	// PenaltyDecayInterval is the time taken for a single penalty point to decay.
	// This determines how long the "memory" of the system is -- i.e. how long
	// it takes for an offender to return to zero-penalty after requests stop.
	//
	// The penalty score increments by 1.0 for each successful call to Allow.
	//
	// Because the penalty only increments on success, and a success requires
	// waiting for the backoff to expire, the wait time between attempts
	// can never exceed PenaltyDecayInterval
	//
	// Defaults to 60s
	PenaltyDecayInterval time.Duration

	// GrowthFactor controls how aggressively wait times ramp up.
	// A factor of 2.0 doubles for each subsequent successful Allow.
	// Defaults to 2
	GrowthFactor float64
	// contains filtered or unexported fields
}

func (*LimiterOpts) Sanitize

func (o *LimiterOpts) Sanitize() error

Sanitize checks LimiterOpts fields and sets defaults. It is strict about correctness of field values, optimising for clarity, rejecting nonsensical configurations.

type LocalKeyedLimiter

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

LocalKeyedLimiter is designed to mimic the redis-powered RedisKeyedLimiter, but implements its algorithm locally in Go.

func NewLocalKeyedLimiter

func NewLocalKeyedLimiter(opts LimiterOpts) (*LocalKeyedLimiter, error)

func (*LocalKeyedLimiter) Allow

func (l *LocalKeyedLimiter) Allow(ctx context.Context, key string) (ok bool, wait time.Duration, err error)

func (*LocalKeyedLimiter) Reset

func (l *LocalKeyedLimiter) Reset(ctx context.Context, key string) error

type LocalLimiter

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

LocalLimiter implements a single in-memory backoff limiter, mimicking the Redis-powered BackoffLimiter.

func NewLocalLimiter

func NewLocalLimiter(opts *LimiterOpts) (*LocalLimiter, error)

NewLocalLimiter instantiates a single in-memory limiter instance. Opts is a pointer to allow common opts to be shared across multiple instances.

func (*LocalLimiter) Allow

func (l *LocalLimiter) Allow(ctx context.Context) (ok bool, wait time.Duration, err error)

func (*LocalLimiter) Reset

func (l *LocalLimiter) Reset(_ context.Context) error

type RedisKeyedLimiter

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

func NewRedisKeyedLimiter

func NewRedisKeyedLimiter(
	client rueidis.Client,
	opts RedisKeyedLimiterOpts,
) (*RedisKeyedLimiter, error)

NewRedisKeyedLimiter instantiates a new redis-backed keyed backoff limiter. Errors returned will always relate to sanity of the provided opts. It would be reasonable to panic on error, e.g. lo.Must()

func (*RedisKeyedLimiter) Allow

func (l *RedisKeyedLimiter) Allow(ctx context.Context, key string) (ok bool, wait time.Duration, err error)

func (*RedisKeyedLimiter) Reset

func (l *RedisKeyedLimiter) Reset(ctx context.Context, key string) error

type RedisKeyedLimiterOpts

type RedisKeyedLimiterOpts struct {
	LimiterOpts LimiterOpts

	// Redis is the Redis key where the limiter state score should be stored
	// for a given limiter key, e.g. limiter:users_by_ip:{key}
	RedisKey func(key string) string
}

func DefaultRedisKeyedLimiterOpts

func DefaultRedisKeyedLimiterOpts(name string, opts LimiterOpts) RedisKeyedLimiterOpts

DefaultRedisKeyedLimiterOpts creates a config that writes to the Redis key "limiter:name:{key}"

func (*RedisKeyedLimiterOpts) Sanitize

func (o *RedisKeyedLimiterOpts) Sanitize() error

type RedisLimiter

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

RedisLimiter wraps a RedisKeyedLimiter and limits to a single key

func NewRedisLimiter

func NewRedisLimiter(
	client rueidis.Client,
	opts RedisLimiterOpts,
) (*RedisLimiter, error)

func (*RedisLimiter) Allow

func (l *RedisLimiter) Allow(ctx context.Context) (ok bool, wait time.Duration, err error)

func (*RedisLimiter) Reset

func (l *RedisLimiter) Reset(ctx context.Context) error

type RedisLimiterOpts

type RedisLimiterOpts struct {
	LimiterOpts LimiterOpts

	// RedisKey is the Redis key where the limiter state should be stored,
	// e.g. limiter:{my_global_action}
	RedisKey string
}

func DefaultRedisLimiterOpts

func DefaultRedisLimiterOpts(name string, opts LimiterOpts) RedisLimiterOpts

DefaultRedisLimiterOpts creates a config that writes to the Redis keys "limiter:name"

func (*RedisLimiterOpts) Sanitize

func (o *RedisLimiterOpts) Sanitize() error

Jump to

Keyboard shortcuts

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