Skip to content
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

[count-inc] Add decrement logic to the incoming function #843

Merged
merged 4 commits into from
Sep 14, 2018

Conversation

y-tabata
Copy link
Contributor

Closes #830.

@y-tabata y-tabata requested a review from a team as a code owner August 14, 2018 05:39
@@ -1,29 +1,68 @@
local loader = require 'apicast.configuration_loader.remote_v1'
local _M = require 'apicast.configuration_loader.remote_v1'
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

@@ -194,7 +194,7 @@ describe('Rate limit policy', function()
assert(rate_limit_policy:access(context))
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'))
Copy link
Contributor

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?

Copy link
Contributor Author

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

@@ -33,6 +33,17 @@ function _M.incoming(self, key, commit)
if not count then
return nil, err
end

if count > limit then
count, err = dict:incr(key, -1)
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

@mikz mikz Sep 7, 2018

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 mikz changed the base branch from master to 3.3-stable September 14, 2018 09:32
Copy link
Contributor

@mikz mikz left a 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 👍 .

@mikz mikz merged commit c87a510 into 3scale:3.3-stable Sep 14, 2018
@y-tabata y-tabata deleted the count-inc-decr branch September 14, 2018 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants