package ratelimit import ( "time" "github.com/supabase/auth/internal/conf" "golang.org/x/time/rate" ) const defaultOverTime = time.Hour // BurstLimiter wraps the golang.org/x/time/rate package. type BurstLimiter struct { rl *rate.Limiter } // NewBurstLimiter returns a rate limiter configured using the given conf.Rate. // // The returned Limiter will be configured with a token bucket containing a // single token, which will fill up at a rate of 1 event per r.OverTime with // an initial burst amount of r.Events. // // For example: // - 1/10s is 1 events per 10 seconds with burst of 1. // - 1/2s is 1 events per 2 seconds with burst of 1. // - 10/10s is 1 events per 10 seconds with burst of 10. // // If Rate.Events is <= 0, the burst amount will be set to 1. // // See Example_newBurstLimiter for a visualization. func NewBurstLimiter(r conf.Rate) *BurstLimiter { // The rate limiter deals in events per second. d := r.OverTime if d <= 0 { d = defaultOverTime } e := r.Events if e <= 0 { e = 0 } // BurstLimiter will have an initial token bucket of size `e`. It will // be refilled at a rate of 1 per duration `d` indefinitely. rl := &BurstLimiter{ rl: rate.NewLimiter(rate.Every(d), int(e)), } return rl } // Allow implements Limiter by calling AllowAt with the current time. func (l *BurstLimiter) Allow() bool { return l.AllowAt(time.Now()) } // AllowAt implements Limiter by calling the underlying x/time/rate.Limiter // with the given time. func (l *BurstLimiter) AllowAt(at time.Time) bool { return l.rl.AllowN(at, 1) }