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
x/time: Reserve on zero rate limiter allows infinite reservations (because of divide by zero) #47221
Comments
cc @Sajmani |
Same underlying cause: #39984. But this report additionally describes an issue with
|
CL https://go-review.googlesource.com/c/time/+/323429 mentions the linked issue, but hasn't been reviewed completely yet. |
@mpl: I agree with the overall issue. But not the following:
I don't think this would be correct based on the existing Limiter docs, copied below. Particularly, the burst must also be considered; it is not sufficient to consider only the zero Limit and return a non-ok reservation. So the first call to Reserve, even with a zero Limiter, should return an ok reservation if the burst > 0.
|
Sure. Everything I said should of course take into account the burst as
well.
…On Sun, Jul 18, 2021, 19:48 Nishanth Shanmugham ***@***.***> wrote:
@mpl <https://github.com/mpl>: Reserve, which imho should always return
non ok reservation if it is on a Limiter that was initialized with a zero
Limit
I don't think this would be correct based on the existing Limiter docs,
copied below:
A Limiter controls how frequently events are allowed to happen. It
implements a "token bucket" of size b, initially full and refilled at rate
r tokens per second.
Particularly, the burst must also be considered; it is not sufficient to
consider only the zero Limit and return a non-ok reservation. So the first
call to Reserve, even with a zero Limiter, should return an ok reservation
if the burst > 0.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#47221 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAEY3F5SFKMOP3IBSDPPHGTTYMHXLANCNFSM5AN2NWHA>
.
|
We should certainly fix the division by zero (#2 in your summary). |
@Sajmani just as one data point, in https://github.com/traefik/traefik we are one of these users of Reserve (and we actually rely on the "broken" behaviour in question), but we'll be ready to adapt if the behaviour changes. I personally think that the behaviour should change because it irks me that it does not behave consistently with how Allow does at zero, but I understand your concerns. |
The root cause of this issue was fixed in f0f3c7e86c11ca8f8b99d970e28445dda0b41195 (https://go-review.googlesource.com/c/time/+/323429) so as far as I'm concerned we can clean things up now. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes (with go version go1.16.6 darwin/amd64)
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Consider these two, that only differ in their argument to NewLimiter:
The behaviour at zero happens afaict because in:
there is no safeguard for a division by a limit at zero, which means seconds is then Inf. Then it gets "worse" because the final operation is an overflow, so the returned number is a huge negative (-9223372036854775808).
Then in reserveN, we have:
which results in the reservation being ok, because of the huge negative.
And in addition, in DelayFrom, we have:
which explains why we always get a zero delay instead of an increasingly large delay when we pile on the reservations on the Limiter.
So in summary, I think we have
What did you expect to see?
I expected Reserve to return a non-ok reservation on a Limiter initialized with a zero Limit. And if not, I would at least expect the resulting reservation to not have a delay of zero.
What did you see instead?
Reserve returns an ok reservation, with a zero delay.
The text was updated successfully, but these errors were encountered: