-
Notifications
You must be signed in to change notification settings - Fork 402
/
ratelimit.go
44 lines (36 loc) · 1.14 KB
/
ratelimit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
package contact
import (
"fmt"
"time"
"golang.org/x/time/rate"
"storj.io/common/lrucache"
)
// RateLimiter allows to prevent multiple events in fixed period of time.
type RateLimiter struct {
limiters *lrucache.ExpiringLRU
interval time.Duration // interval during which events are not limiting.
burst int // maximum number of events allowed during duration.
}
// NewRateLimiter is a constructor for RateLimiter.
func NewRateLimiter(interval time.Duration, burst, numLimits int) *RateLimiter {
return &RateLimiter{
limiters: lrucache.New(lrucache.Options{Expiration: -1, Capacity: numLimits}),
interval: interval,
burst: burst,
}
}
// IsAllowed indicates if event is allowed to happen.
func (rateLimiter *RateLimiter) IsAllowed(key string) bool {
limiter, err := rateLimiter.limiters.Get(key, func() (interface{}, error) {
return rate.NewLimiter(
rate.Limit(time.Second)/rate.Limit(rateLimiter.interval),
rateLimiter.burst,
), nil
})
if err != nil {
panic(fmt.Sprintf("unreachable: %+v", err))
}
return limiter.(*rate.Limiter).Allow()
}