0

关于 time/rate 中取消返回 token 的问题(bug?)

 2 years ago
source link: https://www.v2ex.com/t/877175
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Go 编程语言

关于 time/rate 中取消返回 token 的问题(bug?)

  AugOmin · 刚刚 · 1 次点击

官方包golang.org/x/time中 cancel 的部分,返回 token 的代码( CancelAt )

https://github.com/golang/time/blob/e5dcc9cfc0b9553953e355dde5bdf4ff9f82f742/rate/rate.go#L168

	// calculate tokens to restore
	// The duration between lim.lastEvent and r.timeToAct tells us how many tokens were reserved
	// after r was obtained. These tokens should not be restored.
    // 这行代码多减了一次最近申请的预支的 token ,用测试代码说明一下
	restoreTokens := float64(r.tokens) - r.limit.tokensFromDuration(r.lim.lastEvent.Sub(r.timeToAct))
	if restoreTokens <= 0 {
		return
	}
	// advance time to now
	now, _, tokens := r.lim.advance(now)
	// calculate new number of tokens
	tokens += restoreTokens
	if burst := float64(r.lim.burst); tokens > burst {
		tokens = burst
	}

t0 := time.Now()

l := NewLimiter(1, 10)
l.ReserveN(t0, 5)       //桶里还剩 -5 个 token
r := l.ReserveN(t0, 10) // 桶里还剩 -5 个 token
fmt.Printf("%+v\n", l)

// 最后结果还剩 8 个 token
l.ReserveN(t0, 2) // 桶里还有 -7 个
fmt.Printf("%+v\n", l)
//
r.CancelAt(t0) // -7 + (10 - 2) = 1
fmt.Printf("%+v\n", l)

l.ReserveN(t0, 8) // -7
fmt.Printf("%+v\n", l)
// 这样到了第七秒就只消费了 5+8+2=15 ,而取消之前应该是 5+10+2=17 ,取消之后 token 的总数变少了

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK