Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to understand New(time.Second*1, 5) #1

Open
nydw opened this issue Mar 20, 2017 · 0 comments
Open

How to understand New(time.Second*1, 5) #1

nydw opened this issue Mar 20, 2017 · 0 comments

Comments

@nydw
Copy link

nydw commented Mar 20, 2017

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.Second
1, 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.Second
1, 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()
	}

}()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant