Skip to content

Commit d5354a9

Browse files
committed
optimize how xds bootstrap fills in default values for node.ClientFeatures
1 parent 75919fe commit d5354a9

File tree

4 files changed

+85
-2
lines changed

4 files changed

+85
-2
lines changed

xds/googledirectpath/googlec2p_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func TestBuildXDS(t *testing.T) {
199199
Locality: &v3corepb.Locality{Zone: testZone},
200200
UserAgentName: gRPCUserAgentName,
201201
UserAgentVersionType: &v3corepb.Node_UserAgentVersion{UserAgentVersion: grpc.Version},
202-
ClientFeatures: []string{clientFeatureNoOverprovisioning},
202+
ClientFeatures: []string{clientFeatureNoOverprovisioning, clientFeatureResourceWrapper},
203203
}
204204
if tt.ipv6 {
205205
wantNode.Metadata = &structpb.Struct{

xds/internal/xdsclient/bootstrap/bootstrap.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ func newConfigFromContents(data []byte) (*Config, error) {
565565
}
566566
node.UserAgentName = gRPCUserAgentName
567567
node.UserAgentVersionType = &v3corepb.Node_UserAgentVersion{UserAgentVersion: grpc.Version}
568-
node.ClientFeatures = append(node.ClientFeatures, clientFeatureNoOverprovisioning, clientFeatureResourceWrapper)
568+
node.ClientFeatures = AppendIfNotPresent(node.ClientFeatures, clientFeatureNoOverprovisioning, clientFeatureResourceWrapper)
569569
config.NodeProto = node
570570

571571
logger.Debugf("Bootstrap config for creating xds-client: %v", pretty.ToJSON(config))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
*
3+
* Copyright 2024 gRPC authors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package bootstrap
20+
21+
// AppendIfNotPresent adds elems to a slice while ignoring duplicates
22+
func AppendIfNotPresent[E comparable](slice []E, elems ...E) []E {
23+
presented := make(map[E]struct{})
24+
25+
for _, s := range slice {
26+
presented[s] = struct{}{}
27+
}
28+
29+
for _, e := range elems {
30+
if _, ok := presented[e]; !ok {
31+
slice = append(slice, e)
32+
presented[e] = struct{}{}
33+
}
34+
}
35+
return slice
36+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
*
3+
* Copyright 2024 gRPC authors.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package bootstrap
20+
21+
import (
22+
"reflect"
23+
"testing"
24+
)
25+
26+
func TestAppendIfNotPresent(t *testing.T) {
27+
type args struct {
28+
slice []string
29+
elems []string
30+
}
31+
tests := []struct {
32+
name string
33+
args args
34+
want []string
35+
}{
36+
{name: "empty", args: args{[]string{}, []string{"a"}}, want: []string{"a"}},
37+
{name: "just append", args: args{[]string{"a"}, []string{"b"}}, want: []string{"a", "b"}},
38+
{name: "ignore a", args: args{[]string{"a"}, []string{"a", "b"}}, want: []string{"a", "b"}},
39+
}
40+
for _, tt := range tests {
41+
t.Run(tt.name, func(t *testing.T) {
42+
if got := AppendIfNotPresent(tt.args.slice, tt.args.elems...); !reflect.DeepEqual(got, tt.want) {
43+
t.Errorf("appendIfNotPresent() = %v, want %v", got, tt.want)
44+
}
45+
})
46+
}
47+
}

0 commit comments

Comments
 (0)