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

fix(dao) apply cache_key for target uniqueness detection #8179

Conversation

yankun-li-kong
Copy link
Contributor

@yankun-li-kong yankun-li-kong commented Dec 12, 2021

Summary

Apply cache_key for target uniqueness detection
Improvement for #6483

Full changelog

  • Add new cache_key(upstream, target) in targets table for uniqueness detection.
  • Delete useless targets uniqueness detection functions.
  • Targets API returns 409 when creating/updating delicate targets.
  • Add migration functions to add cache_key column, delete duplicate targets, add cache_key for existing targets.

Issues resolved

CT-97

@yankun-li-kong
Copy link
Contributor Author

yankun-li-kong commented Dec 13, 2021

Hi @locao would like to discuss below points

I have deleted the functions you wrote in kong/api/routes/upstreams.lua.
It will changed the behavior of POST target API.

Before:
POST target API is able to create new targets or update existing targets

After:
POST target API is only able to create new targets (See test case diff)
You have to use PATCH target API to update existing targets

Please let me know your opinion.
I think you may know the reason why we use POST target to update existing targets.

If we want to keep previous behavior(see Before), then I should not modify kong/api/routes/upstreams.lua

@dndx
Copy link
Member

dndx commented Dec 15, 2021

Related to #6483. Please see comments there for context.

return nil, err
end

for _, row in ipairs(rows) do
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: Are there any safety/reentrantcy/atomicity concerns with performing these updates within the SELECT loop? Would it be any safer (or less safe?) to build a full list of rows (exhausting the SELECT iterator) and perform the updates in a separate loop, or is the difference negligible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your suggestion!
I think it should not make much difference as the flow is still the same as below

SELECT from targets and pass targets list to rows
then execute UPDATE targets in a loop with rows

Copy link
Contributor

@locao locao left a comment

Choose a reason for hiding this comment

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

Thanks for bringing this up @yankun-li-kong! That's something we've been waiting for 3.0 to do.

The code seems OK to me, just a few suggestions on the Cassandra migration. My main concern is that we should not merge this change to master at this moment. We are still having another release before 3.0.

return endpoints.handle_error(err_t)
end
if entity then
return kong.response.exit(200, entity, { ["Deprecation"] = "true" })
Copy link
Contributor

Choose a reason for hiding this comment

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

It makes sense to change the POST behaviour, but shouldn't we wait until 3.0 to merge 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.

Got it. Please let me know when we should merge it so I could rename 012_213_to_220.lua file

@@ -0,0 +1,122 @@
-- remove repeated targets, the older ones are not useful anymore. targets with
-- weight 0 will be kept, as we cannot tell which were deleted and which were
-- explicitly set as 0.
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the target history removal in 2.2 we don't keep deleted targets.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I saw kong has run c_remove_unused_targets in 012_213_to_220.lua to delete duplicate targets in 2.2.

But duplicate targets may still exist after that.
Regarding https://github.com/Kong/kong/blob/master/kong/db/dao/targets.lua#L50-L59
kong will do uniqueness detection and then insert targets.
It is not an atomic operation and a duplicate target may be added during the above process.

Comment on lines 16 to 35
upstream_targets[key] = { n = 0 }
end

upstream_targets[key].n = upstream_targets[key].n + 1
upstream_targets[key][upstream_targets[key].n] = { row.id, row.created_at }
end
end

local sort = function(a, b)
return a[2] > b[2]
end

for _, targets in pairs(upstream_targets) do
if targets.n > 1 then
table.sort(targets, sort)

for i = 2, targets.n do
local _, err = coordinator:execute("DELETE FROM targets WHERE id = ?", {
cassandra.uuid(targets[i][1])
})
Copy link
Contributor

Choose a reason for hiding this comment

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

(somehow this comment was not added to my review)

I haven't tested this suggestion, but it seems to me that it's possible to delete the duplicated targets in a single loop.

Suggested change
upstream_targets[key] = { n = 0 }
end
upstream_targets[key].n = upstream_targets[key].n + 1
upstream_targets[key][upstream_targets[key].n] = { row.id, row.created_at }
end
end
local sort = function(a, b)
return a[2] > b[2]
end
for _, targets in pairs(upstream_targets) do
if targets.n > 1 then
table.sort(targets, sort)
for i = 2, targets.n do
local _, err = coordinator:execute("DELETE FROM targets WHERE id = ?", {
cassandra.uuid(targets[i][1])
})
upstream_targets[key] = {
id = row.id,
created_at = row.created_at,
}
else
local to_remove
if row.created_at > upstream_targets[key].created_at then
to_remove = upstream_targets[key].id
upstream_targets[key] = {
id = row.id,
created_at = row.created_at,
}
else
to_remove = row.id
end
local _, err = coordinator:execute("DELETE FROM targets WHERE id = ?", {
cassandra.uuid(to_remove)
})

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed and tested in my local.
It looks much simple than previous one!

@locao locao added this to the 3.0 milestone Dec 16, 2021
@locao locao added the pr/ready (but hold merge) No more concerns, but do not merge yet (probably a conflict of interest with another PR or release) label Dec 16, 2021
@dndx dndx removed the pr/ready (but hold merge) No more concerns, but do not merge yet (probably a conflict of interest with another PR or release) label Mar 30, 2022
@dndx
Copy link
Member

dndx commented Mar 30, 2022

Hello @yankun-li-kong ,

Could you rebase this onto the latest master so it can be ready for merge? Since this will be release in 3.0, a new migration file will be needed. We also need some entry inside the CHANGELOG.md file describing this change.

Add new cache_key(upstream, target) in targets table for uniqueness detection.
Delete useless targets uniqueness detection functions.
Targets API returns 409 when creating/updating delicate targets.
Add migration functions to add cache_key column, delete duplicate targets, add cache_key for existing targets.
Fix spec test, delete unused variable id.
Fix spec test, do not redefine res variable.
Refactor c_remove_unused_targets method to delete duplicate targets in a single loop.
Modify spec test title.
@yankun-li-kong yankun-li-kong force-pushed the fix/apply-cache-key-for-target-uniqueness-detection branch from 6433ab2 to d3e375b Compare April 3, 2022 11:31
@dndx dndx requested a review from locao April 13, 2022 12:24
@yankun-li-kong yankun-li-kong requested a review from a team as a code owner April 19, 2022 05:29
@dndx dndx merged commit 9eba2a1 into Kong:master Apr 19, 2022
kikito added a commit that referenced this pull request Aug 20, 2022
reverted by #8705, the changelog entry was missed
kikito added a commit that referenced this pull request Aug 20, 2022
This reverts commit 4ee96292de57a6ce1eb6b5f55a6502426f47d98d.
aboudreault pushed a commit that referenced this pull request Aug 22, 2022
reverted by #8705, the changelog entry was missed
aboudreault pushed a commit that referenced this pull request Aug 22, 2022
This reverts commit 4ee96292de57a6ce1eb6b5f55a6502426f47d98d.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants