[NET-5589] Optimize leaf watch diff on xds controller. (#18921)

Optimize leaf watch diff on xds controller.
This commit is contained in:
Derek Menteer 2023-09-21 08:11:20 -05:00 committed by GitHub
parent f463ebd569
commit d4ed3047f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 11 deletions

View File

@ -397,18 +397,13 @@ func (r *xdsReconciler) cancelWatches(leafResourceRefs []*pbresource.Reference)
// prevWatchesToCancel computes if there are any items in prevWatchedLeafs that are not in currentLeafs, and returns a list of those items.
func prevWatchesToCancel(prevWatchedLeafs []*pbresource.Reference, currentLeafs []resource.ReferenceOrID) []*pbresource.Reference {
var prevWatchedLeafsToCancel []*pbresource.Reference
prevWatchedLeafsToCancel := make([]*pbresource.Reference, 0, len(prevWatchedLeafs))
newLeafs := make(map[string]struct{})
for _, newLeaf := range currentLeafs {
newLeafs[keyFromReference(newLeaf)] = struct{}{}
}
for _, prevLeaf := range prevWatchedLeafs {
prevKey := keyFromReference(prevLeaf)
found := false
for _, newLeaf := range currentLeafs {
newKey := keyFromReference(newLeaf)
if prevKey == newKey {
found = true
break
}
}
if !found {
if _, ok := newLeafs[keyFromReference(prevLeaf)]; !ok {
prevWatchedLeafsToCancel = append(prevWatchedLeafsToCancel, prevLeaf)
}
}

View File

@ -930,6 +930,68 @@ func (suite *xdsControllerTestSuite) setupFooBarProxyStateTemplateAndEndpoints()
suite.expectedBarProxyStateEndpoints = expectedBarProxyStateEndpoints
}
func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() {
makeRef := func(names ...string) []*pbresource.Reference {
out := make([]*pbresource.Reference, len(names))
for i, name := range names {
out[i] = &pbresource.Reference{
Name: name,
Type: &pbresource.Type{
Group: "g",
GroupVersion: "v",
Kind: "k",
},
Tenancy: &pbresource.Tenancy{},
}
}
return out
}
convert := func(input []*pbresource.Reference) []resource.ReferenceOrID {
asInterface := make([]resource.ReferenceOrID, len(input))
for i := range input {
asInterface[i] = input[i]
}
return asInterface
}
cases := []struct {
old []*pbresource.Reference
new []*pbresource.Reference
expect []*pbresource.Reference
}{
{
old: makeRef("a", "b", "c"),
new: makeRef("a", "c"),
expect: makeRef("b"),
},
{
old: makeRef("a", "b", "c"),
new: makeRef("a", "b", "c"),
expect: makeRef(),
},
{
old: makeRef(),
new: makeRef("a", "b"),
expect: makeRef(),
},
{
old: makeRef("a", "b"),
new: makeRef(),
expect: makeRef("a", "b"),
},
{
old: makeRef(),
new: makeRef(),
expect: makeRef(),
},
}
for _, tc := range cases {
toCancel := prevWatchesToCancel(tc.old, convert(tc.new))
require.ElementsMatch(suite.T(), toCancel, tc.expect)
}
}
func TestXdsController(t *testing.T) {
suite.Run(t, new(xdsControllerTestSuite))
}