Documentation ¶
Overview ¶
Package ratelimit provides a simple window-based rate limiter.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Limiter ¶
type Limiter struct { sync.Mutex WindowLimits []WindowLimit // contains filtered or unexported fields }
Limiter is a simple rate limiter with one or more fixed windows, e.g. the last minute/hour/day/week, working on three classes/subnets of an IP.
Example ¶
package main import ( "fmt" "net" "time" "github.com/mjl-/mox/ratelimit" ) func main() { // Make a new rate limit that has maxima per minute, hour and day. The maxima are // tracked per ipmasked1 (ipv4 /32 or ipv6 /64), ipmasked2 (ipv4 /26 or ipv6 /48) // and ipmasked3 (ipv4 /21 or ipv6 /32). // // It is common to allow short bursts (with a narrow window), but not allow a high // sustained rate (with wide window). limit := ratelimit.Limiter{ WindowLimits: []ratelimit.WindowLimit{ {Window: time.Minute, Limits: [...]int64{2, 3, 4}}, {Window: time.Hour, Limits: [...]int64{4, 6, 8}}, {Window: 24 * time.Hour, Limits: [...]int64{20, 40, 60}}, }, } tm, _ := time.Parse(time.RFC3339, "2006-01-02T15:04:05Z") fmt.Println("1:", limit.Add(net.ParseIP("127.0.0.1"), tm, 1)) // Success. fmt.Println("2:", limit.Add(net.ParseIP("127.0.0.1"), tm, 1)) // Success. fmt.Println("3:", limit.Add(net.ParseIP("127.0.0.1"), tm, 1)) // Failure, too many from same ip. fmt.Println("4:", limit.Add(net.ParseIP("127.0.0.2"), tm, 1)) // Success, different IP, though nearby. fmt.Println("5:", limit.Add(net.ParseIP("127.0.0.2"), tm, 1)) // Failure, hits ipmasked2 check. fmt.Println("6:", limit.Add(net.ParseIP("127.0.0.1"), tm.Add(time.Minute), 1)) // Success, in next minute. fmt.Println("7:", limit.Add(net.ParseIP("127.0.0.1"), tm.Add(2*time.Minute), 1)) // Success, in another minute. fmt.Println("8:", limit.Add(net.ParseIP("127.0.0.1"), tm.Add(3*time.Minute), 1)) // Failure, hitting hourly window for ipmasked1. limit.Reset(net.ParseIP("127.0.0.1"), tm.Add(3*time.Minute)) fmt.Println("9:", limit.Add(net.ParseIP("127.0.0.1"), tm.Add(3*time.Minute), 1)) // Success. }
Output: 1: true 2: true 3: false 4: true 5: false 6: true 7: true 8: false 9: true
func (*Limiter) Add ¶
Add attempts to consume "n" items from the rate limiter. If the total for this key and this interval would exceed limit, "n" is not counted and false is returned. If now represents a different time interval, all counts are reset.
Click to show internal directories.
Click to hide internal directories.