Skip to content

Commit 48f48c1

Browse files
authored
balancer/pickfirstleaf: Avoid reading Address.Metadata (#8227) (#8259)
1 parent fd6f585 commit 48f48c1

File tree

2 files changed

+81
-2
lines changed

2 files changed

+81
-2
lines changed

balancer/pickfirst/pickfirstleaf/pickfirstleaf.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,5 @@ func (al *addressList) hasNext() bool {
923923
// fields that are meaningful to the SubConn.
924924
func equalAddressIgnoringBalAttributes(a, b *resolver.Address) bool {
925925
return a.Addr == b.Addr && a.ServerName == b.ServerName &&
926-
a.Attributes.Equal(b.Attributes) &&
927-
a.Metadata == b.Metadata
926+
a.Attributes.Equal(b.Attributes)
928927
}

balancer/pickfirst/pickfirstleaf/pickfirstleaf_ext_test.go

+80
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
"google.golang.org/grpc/internal/testutils"
4242
"google.golang.org/grpc/internal/testutils/pickfirst"
4343
"google.golang.org/grpc/internal/testutils/stats"
44+
"google.golang.org/grpc/metadata"
4445
"google.golang.org/grpc/resolver"
4546
"google.golang.org/grpc/resolver/manual"
4647
"google.golang.org/grpc/status"
@@ -1424,6 +1425,85 @@ func (s) TestPickFirstLeaf_HealthUpdates(t *testing.T) {
14241425
testutils.AwaitState(ctx, t, cc, connectivity.TransientFailure)
14251426
}
14261427

1428+
// Tests the case where an address update received by the pick_first LB policy
1429+
// differs in metadata which should be ignored by the LB policy. In this case,
1430+
// the test verifies that new connections are not created when the address
1431+
// update only changes the metadata.
1432+
func (s) TestPickFirstLeaf_AddressUpdateWithMetadata(t *testing.T) {
1433+
dialer := testutils.NewBlockingDialer()
1434+
dopts := []grpc.DialOption{
1435+
grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"loadBalancingConfig": [{"%s":{}}]}`, pickfirstleaf.Name)),
1436+
grpc.WithContextDialer(dialer.DialContext),
1437+
}
1438+
cc, r, backends := setupPickFirstLeaf(t, 2, dopts...)
1439+
1440+
// Add a metadata to the addresses before pushing them to the pick_first LB
1441+
// policy through the manual resolver.
1442+
addrs := backends.resolverAddrs()
1443+
for i := range addrs {
1444+
addrs[i].Metadata = &metadata.MD{
1445+
"test-metadata-1": []string{fmt.Sprintf("%d", i)},
1446+
}
1447+
}
1448+
r.UpdateState(resolver.State{Addresses: addrs})
1449+
1450+
// Ensure that RPCs succeed to the expected backend.
1451+
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
1452+
defer cancel()
1453+
if err := pickfirst.CheckRPCsToBackend(ctx, cc, addrs[0]); err != nil {
1454+
t.Fatal(err)
1455+
}
1456+
1457+
// Create holds for each backend. This will be used to verify the connection
1458+
// is not re-established.
1459+
holds := backends.holds(dialer)
1460+
1461+
// Add metadata to the addresses before pushing them to the pick_first LB
1462+
// policy through the manual resolver. Leave the order of the addresses
1463+
// unchanged.
1464+
for i := range addrs {
1465+
addrs[i].Metadata = &metadata.MD{
1466+
"test-metadata-2": []string{fmt.Sprintf("%d", i)},
1467+
}
1468+
}
1469+
r.UpdateState(resolver.State{Addresses: addrs})
1470+
1471+
// Ensure that no new connection is established.
1472+
for i := range holds {
1473+
sCtx, sCancel := context.WithTimeout(ctx, defaultTestShortTimeout)
1474+
defer sCancel()
1475+
if holds[i].Wait(sCtx) {
1476+
t.Fatalf("Unexpected connection attempt to backend: %s", addrs[i])
1477+
}
1478+
}
1479+
1480+
if err := pickfirst.CheckRPCsToBackend(ctx, cc, addrs[0]); err != nil {
1481+
t.Fatal(err)
1482+
}
1483+
1484+
// Add metadata to the addresses before pushing them to the pick_first LB
1485+
// policy through the manual resolver. Reverse of the order of addresses.
1486+
for i := range addrs {
1487+
addrs[i].Metadata = &metadata.MD{
1488+
"test-metadata-3": []string{fmt.Sprintf("%d", i)},
1489+
}
1490+
}
1491+
addrs[0], addrs[1] = addrs[1], addrs[0]
1492+
r.UpdateState(resolver.State{Addresses: addrs})
1493+
1494+
// Ensure that no new connection is established.
1495+
for i := range holds {
1496+
sCtx, sCancel := context.WithTimeout(ctx, defaultTestShortTimeout)
1497+
defer sCancel()
1498+
if holds[i].Wait(sCtx) {
1499+
t.Fatalf("Unexpected connection attempt to backend: %s", addrs[i])
1500+
}
1501+
}
1502+
if err := pickfirst.CheckRPCsToBackend(ctx, cc, addrs[1]); err != nil {
1503+
t.Fatal(err)
1504+
}
1505+
}
1506+
14271507
// healthListenerCapturingCCWrapper is used to capture the health listener so
14281508
// that health updates can be mocked for testing.
14291509
type healthListenerCapturingCCWrapper struct {

0 commit comments

Comments
 (0)