-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlimiter.go
75 lines (61 loc) · 1.27 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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package goutils
import (
"sync/atomic"
"time"
)
/**
@author : Jerbe - The porter from Earth
@time : 2023/10/6 11:17
@describe :
*/
// Limiter 数量限定器
type Limiter struct {
// last 最后一次时间
last time.Time
// rate 速率
rate time.Duration
// count 剩余多少数量
count int64
// size 可容纳数量
size int64
}
// getFillCount 获取需要填充数量
func (l *Limiter) getFillCount() int64 {
c := atomic.LoadInt64(&l.count)
if c >= l.size {
return 0
}
if !l.last.IsZero() {
// 获取得出需要填充的数量
cnt := int64(time.Now().Sub(l.last) / l.rate)
// 限定填充数量不能超过限定总大小
if l.size-c >= cnt {
return cnt
} else {
return l.size - l.count
}
}
return l.size
}
// fill 填充数量
func (l *Limiter) fill() {
atomic.AddInt64(&l.count, l.getFillCount())
}
// Allow 判断是否允许通过
func (l *Limiter) Allow() bool {
l.fill()
if atomic.LoadInt64(&l.count) > 0 {
atomic.AddInt64(&l.count, -1)
l.last = time.Now()
return true
}
return false
}
// SetSize 设置大小
func (l *Limiter) SetSize(val int64) {
l.size = val
}
// NewLimiter 返回新的限制器
func NewLimiter(size int64, rate time.Duration) *Limiter {
return &Limiter{size: size, rate: rate, count: size}
}