-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlimiter.go
57 lines (46 loc) · 1.03 KB
/
limiter.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
45
46
47
48
49
50
51
52
53
54
55
56
57
package buttonoff
import (
"sync"
"time"
"golang.org/x/time/rate"
)
type Accepter interface {
Accept(key string) bool
}
type pressRateLimiter struct {
limit rate.Limit
mu *sync.RWMutex
keys map[string]*rate.Limiter
}
func NewPressRateLimiter(period time.Duration) *pressRateLimiter {
limit := rate.Every(period)
return &pressRateLimiter{
limit: limit,
mu: &sync.RWMutex{},
keys: make(map[string]*rate.Limiter),
}
}
func (press *pressRateLimiter) newLimiter() *rate.Limiter {
// Burst of 1 allows the first invocation to use the token, bursting
// as the first "allow".
return rate.NewLimiter(press.limit, 1)
}
func (press *pressRateLimiter) Accept(key string) bool {
press.mu.RLock()
limiter, ok := press.keys[key]
press.mu.RUnlock()
if ok {
return limiter.Allow()
}
// Double check.
press.mu.Lock()
defer press.mu.Unlock()
limiter, ok = press.keys[key]
if ok {
return limiter.Allow()
}
// Or setup a new rate limiter.
limiter = press.newLimiter()
press.keys[key] = limiter
return limiter.Allow()
}