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/rate: expose the number of remaining tokens #50035
Comments
This proposal has been added to the active column of the proposals project |
/cc @Sajmani |
If we expose the tokens, I think we'd instead expose TokensAt(time.Time), externalizing the time.Now() to the caller. I'm curious about the metric you want to expose, though. You can't really interpret Tokens without Burst and Limit. Since we expose SetBurst and SetLimit, in theory you'd want to read tokens, burst, and limit simultaneously with the lock held. That suggests we might want a single method StateAt(time.Time) (limit Limit, burst int, tokens float64). But perhaps this is overkill, since most use cases never call SetBurst or SetLimit. Assuming you're OK calling TokensAt separately from burst & limit (or just saving those from construction), TokensAt seems fine. (And maybe we should include Tokens as a wrapper for TokensAt(time.Now()) for completeness). |
On surface I think this would be a good addition, but part of me feels that the default rate limiter is becoming too much of a catch-all right now. Beyond metrics, I can see this being used to allow an N-priority messages passed the rate limiter only if there are M tokens remaining. Then Higher-priority messages could still pushed through up until the rate limiter is completely full even if swamped with lower priority messages. However, this example feels like it might be better implemented with a custom rate limiter where you can pass options to the reserve, and in a safe manner. |
It seems like a prioritized rate limiter would make sense as a wrapper
around this rate limiter; we don't want to keep making this limiter bigger.
In this case, we're exposing existing state that's documented in the API
(the number of tokens), which seems OK.
S
|
True, but most of the time I see this being used burst and limit aren't being changed. Narrowing to just the metric case, I'm probably going to be viewing this as a line over time, and changes to qps and limit would be very obvious (qps change means line recovers faster, limit change means line maxes out higher). I realize that's a pretty specific justification for my use case, but just wanted to point out that a best effort mechanism was all I was looking for. Happy to see the api expanded though like you describe @Sajmani |
It sounds like adding Tokens by itself is not useful, and then it's unclear how much more API to add after that. Given that rate.Limiter is <50 lines of code, perhaps it would make sense for limiters with special requirements to just start there (or not) and live outside the x repos? |
@rsc |
@rsc Given that rate.Limiter already exposes Burst and Limit as thread-safe accessors, I think it's reasonable to expose Tokens as well. Since Tokens is calculated relative to a specific time using Limiter.advance, I propose defining Tokens as TokensAt(time.Now()), and TokensAt(t) as returning the newTokens from advance(t). |
What is the new API being proposed? |
Add
Optionally add
|
Does anyone object to the API in #50035 (comment)? @ryanmcnamara does that API solve your use case? Thanks. |
Based on the discussion above, this proposal seems like a likely accept. |
No change in consensus, so accepted. 🎉 |
Implemented in https://go-review.googlesource.com/c/time/+/423042 |
Change https://go.dev/cl/423042 mentions this issue: |
rate.Limiter
holds the remaining tokens in a bucket here https://github.com/golang/time/blob/master/rate/rate.go#L59The feature request is to expose this value in a read only way, perhaps as a public function
Tokens
.The use case is that when using a limiter it would be nice to be able to see how many tokens remain without attempting to use one. For my specific case, I want to emit a metric from my kubernetes controller indicating how many tokens are left in the client side rate limiter for a kubernetes clientset (which uses a rate.Limiter under the hood). I think this should be useful in other situations as well though.
Open to any other workarounds as well!
I'd be happy to contribute this, the Tokens func is probably just
I'll create a real PR (and get my contribution environment set up) if this idea sounds reasonable. Thanks!
The text was updated successfully, but these errors were encountered: