ratelimit

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package ratelimit counts requests in fixed time windows, stored in Postgres so every API instance shares the counts.

A limit of "10 per hour" counts per clock hour. Near the boundary of two windows up to twice the limit can get through in a short burst: the trade for a single atomic statement per check.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Email

func Email(email string) string

Email returns the subject for an email address: the SHA-256 of its lower-case form, so the table holds no addresses.

func IP

func IP(ip *netip.Addr) string

IP returns the subject for a client address: the address itself for IPv4, and its /64 for IPv6, since one device can use many addresses in its block.

Types

type Limiter

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

Limiter counts requests against rules.

func New

func New(conn db.DBTX, now func() time.Time) *Limiter

New returns a Limiter using conn. now supplies the current time; pass time.Now outside tests.

func (*Limiter) DeleteEnded

func (l *Limiter) DeleteEnded(ctx context.Context) (int64, error)

DeleteEnded removes the counters of windows that have ended, and returns how many were removed.

func (*Limiter) Hit

func (l *Limiter) Hit(ctx context.Context, rule Rule, subject string) (ok bool, retryAfter time.Duration, err error)

Hit counts one more request by subject under rule, and reports whether it's within the limit. Over the limit, retryAfter is how long until the window ends.

func (*Limiter) HitUndoable added in v1.2.0

func (l *Limiter) HitUndoable(ctx context.Context, rule Rule, subject string) (ok bool, retryAfter time.Duration, undo func(context.Context) error, err error)

HitUndoable is Hit for a limit on failures, where whether a request failed is only known after it's been handled. Counting it first means concurrent requests can't all get past the limit before any failure is counted. If the request turns out not to have failed, call undo to take the hit back. undo is nil when ok is false or err is set.

func (*Limiter) Reached

func (l *Limiter) Reached(ctx context.Context, rule Rule, subject string) (reached bool, retryAfter time.Duration, err error)

Reached reports whether subject has already used up rule's limit, without counting a request. It's for limits on failures, which are counted with Hit only once a request has failed.

type Rule

type Rule struct {
	// Name identifies the limit in keys, e.g. "login:ip".
	Name   string
	Limit  int
	Window time.Duration
}

Rule is one limit: at most Limit requests per Window for each subject.

Jump to

Keyboard shortcuts

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