-
Notifications
You must be signed in to change notification settings - Fork 172
[count-inc] Add decrement logic to the incoming function #843
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
Conversation
| @@ -1,29 +1,68 @@ | |||
| local loader = require 'apicast.configuration_loader.remote_v1' | |||
| local _M = require 'apicast.configuration_loader.remote_v1' | |||
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.
This commit is not related to the rest of the PR, so it should be in a different one.
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.
Changed.
| assert.returns_error('limits exceeded', rate_limit_policy:access(context)) | ||
|
|
||
| assert.equal('2', redis:get('11110_fixed_window_test3')) | ||
| assert.equal('1', redis:get('11110_fixed_window_test3')) |
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.
I don't fully understand the purpose of this change.
Before, we increased the number of hits even when going over limits. Now we force the value to be at most equal to the limit. Why do we need to do this?
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.
Before, we increased the number of hits even when going over limits.
First, we should not increase the number of hits when going over limits, because we should count the number the client calls the API backend.
The previous behavior is the below:
Case 1:
fixed_window_limiters : [
{ "key" : { "name" : "a"}, "count" : 1, "window" : 10 },
{ "key" : { "name" : "b"}, "count" : 2, "window" : 10 }
]After 2 API requests,
the number of hits 'a' is '1',
the number of hits 'b' is '1'.
-> correct
Case 2:
fixed_window_limiters : [
{ "key" : { "name" : "a"}, "count" : 2, "window" : 10 },
{ "key" : { "name" : "b"}, "count" : 1, "window" : 10 }
]After 2 API requests,
the number of hits 'a' is '1',
the number of hits 'b' is '2'.
-> wrong
4973f82 to
c4231f0
Compare
| end | ||
|
|
||
| if count > limit then | ||
| count, err = dict:incr(key, -1) |
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.
I believe this should be done by the .uncommit that is being called by resty.limit.traffic.
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.
@mikz you mean .uncommit needs to be called here with the condition of i == n, right?
https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/traffic.lua#L27-L29
However resty.limit.conn includes this.
So we should choose which file we edit, resty.limit.traffic and resty.limit.conn, or resty.limit.count-inc.
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.
@y-tabata I think we don't need to change any resty.limit library. We have to use it correctly.
resty.limit.traffic calls :incoming(key, false) until the last limiter which is called as :incoming(key, true). If any of those return an error, it is fine to just exit. Nothing was committed to the database.
When all of them succeed, it tries to call again :incoming(key, true), but in this case, if any of them fails then call :uncommit(key) for all limiters that it already called :incoming.
So I'd suspect our limiters are not rolled back because they are not wrapped in one resty.limit.traffic.
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.
resty.limit.traffic calls :incoming(key, false) until the last limiter which is called as :incoming(key, true). If any of those return an error, it is fine to just exit. Nothing was committed to the database.
Using the current count-inc, I think that when the last limiter, which is called as :incoming(key, true), only returns nil and "rejected", the last one is committed to the database.
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.
Ok. I got it now. Implemented a fix to the upstream library: openresty/lua-resty-limit-traffic@c53f224 (openresty/lua-resty-limit-traffic#34)
I think we can just copy that here.
mikz
left a comment
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.
It is just cosmetically different from
openresty/lua-resty-limit-traffic#34 which is not merged anyway, so 👍 .
Closes #830.