-
-
Notifications
You must be signed in to change notification settings - Fork 562
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
Get rate limit count and remaining time limit. #2081
Conversation
// Simple example... .get("/", ctx -> { NaiveRateLimit.requestPerTimeUnit(ctx, 5, TimeUnit.MINUTES); ConcurrentHashMap<TimeUnit, RateLimiter> limiters = RateLimitUtil.INSTANCE.getLimiters(); int count = limiters.get(TimeUnit.MINUTES).getCounter(ctx); long remainder = limiters.get(TimeUnit.MINUTES).getRemainder(TimeUnit.MILLISECONDS); ctx.result("Count: " + count + " Remainder: " + remainder); })
0e2b2a8
to
4b4a470
Compare
@@ -38,6 +40,14 @@ class RateLimiter(val timeUnit: TimeUnit) { | |||
} | |||
} | |||
} | |||
|
|||
fun getCounter(ctx: Context) : Int? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fun getCounter(ctx: Context) : Int? { | |
fun counter(ctx: Context) : Int? { |
return keyToRequestCount.get(RateLimitUtil.keyFunction(ctx)) | ||
} | ||
|
||
fun getRemainder(timeUnit: TimeUnit) : Long? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fun getRemainder(timeUnit: TimeUnit) : Long? { | |
fun remainder(timeUnit: TimeUnit) : Long? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, why does it take a TimeUnit ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will want a different time unit for the remainder. e.g. take a rate limit of 5 requests per SECOND where the remaining time before the SECOND expires is in MILLISECONDS...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps I could use a float... 0.25 left of your TimeUnit; then you would not need another TimeUnit
Thanks @p4paul ! I could merge this, but the way it's written kind of forces you to do this for each handler where you use the rate limiter. We could provide the rate limiter with a config option to run a lambda, so that you could do something like: NaiveRateLimiter.responseHeaders { ctx ->
"headername" to headerValue
} |
Could do object RateLimitUtil {
var responseHeaderFunction = { ctx: Context, timeUnit: TimeUnit, numRequests: Int -> } // signature could be different
} Then we'd call it for each request: fun incrementCounter(ctx: Context, requestLimit: Int) {
...
RateLimitUtil.responseHeaderFunction(ctx, timeUnit, requestLimit) // signature could be different
} It would be used like this: RateLimitUtil.responseHeaderFunction = { ctx, timeUnit, numRequests ->
ctx.header("X-Rate-Limit-Limit", ...)
ctx.header("X-Rate-Limit-Remaining", ...)
ctx.header("X-Rate-Limit-Reset", ...)
} What do you think? |
I like the lambda implementation for setting the headers. Feel free to discard or edit this PR as needed. |
I'd be happy to assist if you'd like to give it a try ...? 😁 |
41640d2
to
2b4c30d
Compare
765b7d0
to
6faa186
Compare
resolves #2080