hi,
At first ,3ks for your codes. but I have some question.
How can I understand "New(time.Second1, 5)" ? I also read your codes " https://github.com/go-http-utils/ratelimit/blob/master/ratelimit.go", it start at the Line76.
Is it mean than the new bucket can permit 5 tokens per second.
请问,我改怎么理解 New(time.Second1, 5) ? bucket 每秒发放5个token, 是这个意思吗 ?(here rewrite in Chinese, I just be sure that I can spell out my question.)
if it's that mean, Is my test case' output maybe something wrong ?
func TestTokenBucket(t *testing.T) {
t.Run("Should return false when wait reach max duration", func(t testing.T) {
b := New(time.Second1, 5)
defer b.Destory()
fmt.Println("1", time.Now().Unix())
b.Take(1)
fmt.Println("2", time.Now().Unix())
b.Take(1)
fmt.Println("3", time.Now().Unix())
b.Take(1)
fmt.Println("4", time.Now().Unix())
b.Take(1)
fmt.Println("5", time.Now().Unix())
b.Take(1)
// time.Sleep(time.Second * 5)
fmt.Println("6", time.Now().Unix())
b.Take(1)
fmt.Println("7", time.Now().Unix())
b.Take(1)
fmt.Println("8", time.Now().Unix())
b.Take(1)
fmt.Println("9", time.Now().Unix())
b.Take(1)
fmt.Println("0", time.Now().Unix())
})
}
OUTPUT:
1 1489984668
avail: 5
2 1489984668
avail: 4
3 1489984668
avail: 3
4 1489984668
avail: 2
5 1489984668
avail: 1
6 1489984668
avail: 0
7 1489984669
avail: 0
8 1489984670
avail: 0
9 1489984671
avail: 0
0 1489984672
PASS
func New(interval time.Duration, cap int64) *TokenBucket
the first 5 times, it's nothing. but 6 7 8 one per second, generate one token per interval.
https://github.com/go-http-utils/ratelimit/blob/master/ratelimit.go:76
func Handler(h http.Handler, opts Options) http.Handler {
if opts.GetID == nil {
opts.GetID = defaultGetIDFunc
}
if opts.Duration == 0 {
opts.Duration = time.Minute
}
if opts.Count == 0 {
opts.Count = 1000
}
mutex := sync.Mutex{}
bucketsMap := map[string]*bucket.TokenBucket{}
expireMap := expireMap{}
interval := opts.Count / int64(opts.Duration/1e9) * 1e9
// Start a deamon gorouinue to check expiring.
// To take the performance into consideration, the deamon will
// only check at most 1000 buckets or cost at most one second at
// one tick.
go func() {
for now := range time.Tick(opts.Duration) {
mutex.Lock()
hasExpired := true
numExpired := 0
timeLimit := now.Add(time.Second)
for hasExpired && (numExpired < 1000 || now.After(timeLimit)) {
if id, ok := expireMap.getOneExpiredID(); ok {
delete(expireMap, id)
bucketsMap[id].Destory()
delete(bucketsMap, id)
numExpired++
} else {
hasExpired = false
}
}
mutex.Unlock()
}
}()