-
Notifications
You must be signed in to change notification settings - Fork 327
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(xds): Avoid generating duplicate subsets in ingress #1636
Conversation
As a side note I've noticed the same code in OutboudProxyGenerator. I'm wondering if it might be worth adding this dedupe in |
Hey @lahabana, yes I agree - duplicated subsets make no sense for Envoy, this is a good idea to move |
6d1af35
to
5d597de
Compare
Updated @lobkovilya |
I really like the direction you take with this PR, this kind of refactoring was awaited. I want to share some improvement points for this PR, it's not a strict requirement, just a discussion.
func LbSubset(tagSets []envoy.TagKeys, removedTags []string, addedTags []string) {
...
} I'd replace it with: func LbSubset(tagSets []envoy.TagKeys) {
...
} But then we have to call type TagKeysSlice []envoy.TagKeys
func (list TagKeysSlice) Map(f func(item envoy.TagKeys) envoy.TagKeys) TagKeysSlice {
// applies `f` to every item of the list and returns new `list`
}
// With add a list of keys (avoids duplicates)
func With(keys ...string) func(envoy.TagKeys) envoy.TagKeys {
return func(t envoy.TagKeys) envoy.TagKeys {
all := map[string]bool{}
for _, v := range t {
all[v] = true
}
for _, v := range keys {
all[v] = true
}
res := envoy.TagKeys{}
for k := range all {
res = append(res, k)
}
sort.Strings(res)
return res
}
}
// Without removes a list of keys
func Without(keys ...string) func(envoy.TagKeys) envoy.TagKeys {
return func(t envoy.TagKeys) envoy.TagKeys {
all := map[string]bool{}
for _, t := range keys {
all[t] = true
}
res := envoy.TagKeys{}
for _, r := range t {
if !all[r] {
res = append(res, r)
}
}
return res
}
} So now you can call LbSubset(destinationTags.Map(With("mesh")).Map(Without(mesh_proto.ServiceTag)))
What do you think? |
|
Regarding 2. After looking some more at the code there are logical usages of these as Tags and not Selectors so I'm not convinced the rename is justified |
|
47774b9
to
ee464ed
Compare
@lobkovilya updated as we've talked about. |
ee464ed
to
1d58b8d
Compare
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.
Nice! Transformers
looks cool 👍 I have a couple of small comments and 1 comments regarding hashing
pkg/xds/envoy/types.go
Outdated
return out | ||
} | ||
|
||
// Transform applies each transformer to each TagSlice and return a sorted unique TagKeysSlice. |
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.
nit: "to each TagKeys"
pkg/xds/envoy/types.go
Outdated
// Transform applies each transformer to each TagSlice and return a sorted unique TagKeysSlice. | ||
func (t TagKeysSlice) Transform(transformers ...TagKeyTransformer) TagKeysSlice { | ||
allSlices := map[uint64]TagKeys{} | ||
for _, slice := range t { |
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 guess this variable should be named tagKeys
or keys
rather than slice
, right?
pkg/xds/envoy/types.go
Outdated
for _, slice := range t { | ||
res := slice.Transform(transformers...) | ||
if len(res) > 0 { | ||
allSlices[res.Hash()] = res |
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 FNV hash algorithm has some collision rate, even though it's quite low, I'm still concerned about just rewriting the values with the same hash. If it shoots one day we will never debug it. I see 2 options here:
- classic
equal
andbuckets
- build hashes without collisions, tagKeys are not huge it will be fine to convert them to
string
and name it a hash
I like the second approach more since it simpler
pkg/xds/envoy/types.go
Outdated
|
||
func (t Tags) WithoutTag(tag string) Tags { | ||
func (t TagsSlice) ToTagKeySlice() TagKeysSlice { |
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.
nit: ToTagKeysSlice()
In the ingress generator multiple TrafficRoutes with the same destinations would generate duplicated subsets in the edsClusterConfig. As ingress are generated for all meshes this could generate unecessarily complex configuration. This adds uniqueness when generating LbSubsets by using TagKeysSlice.Transformers Signed-off-by: Charly Molter <charly@koyeb.com>
Signed-off-by: Charly Molter <charly@koyeb.com>
1d58b8d
to
18b56c1
Compare
@lobkovilya updated thanks! |
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.
Great work! Thank you for fixing all the comments. Just a little request - please don't force push commits, it's quite complicated to review the difference after review.
Thanks for the review and I won't force push in the future :) |
@lobkovilya can I merge this? |
Sorry, I was about to merge it myself, but it slipped out of my mind. So yes, please, go ahead and merge it 👍 |
In the ingress generator multiple TrafficRoutes with the same destinations
would generate duplicated subsets in the edsClusterConfig.
As ingress are generated for all meshes this could generate unecessarily complex configuration.
This adds uniqueness on the matches
Signed-off-by: Charly Molter charly@koyeb.com