I suspect the following line contains wrong logic.
// 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.
restoreTokens := float64(r.tokens) - r.limit.tokensFromDuration(r.lim.lastEvent.Sub(r.timeToAct))
I think there's no need to subtract tokens reserved after r was obtained, because these tokens are already subtracted at the time their reservation were made in reserveN.
Go version
go version go1.23.0 darwin/arm64
Output of
go env
in your module/workspace:What did you do?
I suspect the following line contains wrong logic.
I think there's no need to subtract tokens reserved after r was obtained, because these tokens are already subtracted at the time their reservation were made in
reserveN
.This stackoverflow post resonates with my idea.
To verify this, I write a test case performing the following scenario:
Say we have an initially full limiter with tokens=burst=10 being refilled at rate=1.
At time=1s, we have only one task worth 1 token to act, and 8 tokens remaining. There's 1 token missing compared to burst=10.
My test code are attached here:
What did you see happen?
The test result is:
What did you expect to see?
There should be 9 tokens remaining at the last line.
(Edited the test code to focus on tokens.)