Skip to content

Commit b0d1203

Browse files
authored
resolver: create AddressMapV2 with generics to replace AddressMap (#8187)
1 parent 43a4a84 commit b0d1203

File tree

5 files changed

+63
-56
lines changed

5 files changed

+63
-56
lines changed

balancer/base/balancer.go

+5-7
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func (bb *baseBuilder) Build(cc balancer.ClientConn, _ balancer.BuildOptions) ba
4141
cc: cc,
4242
pickerBuilder: bb.pickerBuilder,
4343

44-
subConns: resolver.NewAddressMap(),
44+
subConns: resolver.NewAddressMapV2[balancer.SubConn](),
4545
scStates: make(map[balancer.SubConn]connectivity.State),
4646
csEvltr: &balancer.ConnectivityStateEvaluator{},
4747
config: bb.config,
@@ -65,7 +65,7 @@ type baseBalancer struct {
6565
csEvltr *balancer.ConnectivityStateEvaluator
6666
state connectivity.State
6767

68-
subConns *resolver.AddressMap
68+
subConns *resolver.AddressMapV2[balancer.SubConn]
6969
scStates map[balancer.SubConn]connectivity.State
7070
picker balancer.Picker
7171
config Config
@@ -100,7 +100,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
100100
// Successful resolution; clear resolver error and ensure we return nil.
101101
b.resolverErr = nil
102102
// addrsSet is the set converted from addrs, it's used for quick lookup of an address.
103-
addrsSet := resolver.NewAddressMap()
103+
addrsSet := resolver.NewAddressMapV2[any]()
104104
for _, a := range s.ResolverState.Addresses {
105105
addrsSet.Set(a, nil)
106106
if _, ok := b.subConns.Get(a); !ok {
@@ -122,8 +122,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error {
122122
}
123123
}
124124
for _, a := range b.subConns.Keys() {
125-
sci, _ := b.subConns.Get(a)
126-
sc := sci.(balancer.SubConn)
125+
sc, _ := b.subConns.Get(a)
127126
// a was removed by resolver.
128127
if _, ok := addrsSet.Get(a); !ok {
129128
sc.Shutdown()
@@ -173,8 +172,7 @@ func (b *baseBalancer) regeneratePicker() {
173172

174173
// Filter out all ready SCs from full subConn map.
175174
for _, addr := range b.subConns.Keys() {
176-
sci, _ := b.subConns.Get(addr)
177-
sc := sci.(balancer.SubConn)
175+
sc, _ := b.subConns.Get(addr)
178176
if st, ok := b.scStates[sc]; ok && st == connectivity.Ready {
179177
readySCs[sc] = SubConnInfo{Address: addr}
180178
}

balancer/pickfirst/pickfirstleaf/pickfirstleaf.go

+18-22
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func (pickfirstBuilder) Build(cc balancer.ClientConn, bo balancer.BuildOptions)
122122
target: bo.Target.String(),
123123
metricsRecorder: cc.MetricsRecorder(),
124124

125-
subConns: resolver.NewAddressMap(),
125+
subConns: resolver.NewAddressMapV2[*scData](),
126126
state: connectivity.Connecting,
127127
cancelConnectionTimer: func() {},
128128
}
@@ -220,7 +220,7 @@ type pickfirstBalancer struct {
220220
// updates.
221221
state connectivity.State
222222
// scData for active subonns mapped by address.
223-
subConns *resolver.AddressMap
223+
subConns *resolver.AddressMapV2[*scData]
224224
addressList addressList
225225
firstPass bool
226226
numTF int
@@ -319,7 +319,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState
319319
prevAddr := b.addressList.currentAddress()
320320
prevSCData, found := b.subConns.Get(prevAddr)
321321
prevAddrsCount := b.addressList.size()
322-
isPrevRawConnectivityStateReady := found && prevSCData.(*scData).rawConnectivityState == connectivity.Ready
322+
isPrevRawConnectivityStateReady := found && prevSCData.rawConnectivityState == connectivity.Ready
323323
b.addressList.updateAddrs(newAddrs)
324324

325325
// If the previous ready SubConn exists in new address list,
@@ -381,21 +381,21 @@ func (b *pickfirstBalancer) startFirstPassLocked() {
381381
b.numTF = 0
382382
// Reset the connection attempt record for existing SubConns.
383383
for _, sd := range b.subConns.Values() {
384-
sd.(*scData).connectionFailedInFirstPass = false
384+
sd.connectionFailedInFirstPass = false
385385
}
386386
b.requestConnectionLocked()
387387
}
388388

389389
func (b *pickfirstBalancer) closeSubConnsLocked() {
390390
for _, sd := range b.subConns.Values() {
391-
sd.(*scData).subConn.Shutdown()
391+
sd.subConn.Shutdown()
392392
}
393-
b.subConns = resolver.NewAddressMap()
393+
b.subConns = resolver.NewAddressMapV2[*scData]()
394394
}
395395

396396
// deDupAddresses ensures that each address appears only once in the slice.
397397
func deDupAddresses(addrs []resolver.Address) []resolver.Address {
398-
seenAddrs := resolver.NewAddressMap()
398+
seenAddrs := resolver.NewAddressMapV2[*scData]()
399399
retAddrs := []resolver.Address{}
400400

401401
for _, addr := range addrs {
@@ -481,7 +481,7 @@ func addressFamily(address string) ipAddrFamily {
481481
// This ensures that the subchannel map accurately reflects the current set of
482482
// addresses received from the name resolver.
483483
func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address) {
484-
newAddrsMap := resolver.NewAddressMap()
484+
newAddrsMap := resolver.NewAddressMapV2[bool]()
485485
for _, addr := range newAddrs {
486486
newAddrsMap.Set(addr, true)
487487
}
@@ -491,7 +491,7 @@ func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address)
491491
continue
492492
}
493493
val, _ := b.subConns.Get(oldAddr)
494-
val.(*scData).subConn.Shutdown()
494+
val.subConn.Shutdown()
495495
b.subConns.Delete(oldAddr)
496496
}
497497
}
@@ -500,13 +500,12 @@ func (b *pickfirstBalancer) reconcileSubConnsLocked(newAddrs []resolver.Address)
500500
// becomes ready, which means that all other subConn must be shutdown.
501501
func (b *pickfirstBalancer) shutdownRemainingLocked(selected *scData) {
502502
b.cancelConnectionTimer()
503-
for _, v := range b.subConns.Values() {
504-
sd := v.(*scData)
503+
for _, sd := range b.subConns.Values() {
505504
if sd.subConn != selected.subConn {
506505
sd.subConn.Shutdown()
507506
}
508507
}
509-
b.subConns = resolver.NewAddressMap()
508+
b.subConns = resolver.NewAddressMapV2[*scData]()
510509
b.subConns.Set(selected.addr, selected)
511510
}
512511

@@ -539,26 +538,25 @@ func (b *pickfirstBalancer) requestConnectionLocked() {
539538
b.subConns.Set(curAddr, sd)
540539
}
541540

542-
scd := sd.(*scData)
543-
switch scd.rawConnectivityState {
541+
switch sd.rawConnectivityState {
544542
case connectivity.Idle:
545-
scd.subConn.Connect()
543+
sd.subConn.Connect()
546544
b.scheduleNextConnectionLocked()
547545
return
548546
case connectivity.TransientFailure:
549547
// The SubConn is being re-used and failed during a previous pass
550548
// over the addressList. It has not completed backoff yet.
551549
// Mark it as having failed and try the next address.
552-
scd.connectionFailedInFirstPass = true
553-
lastErr = scd.lastErr
550+
sd.connectionFailedInFirstPass = true
551+
lastErr = sd.lastErr
554552
continue
555553
case connectivity.Connecting:
556554
// Wait for the connection attempt to complete or the timer to fire
557555
// before attempting the next address.
558556
b.scheduleNextConnectionLocked()
559557
return
560558
default:
561-
b.logger.Errorf("SubConn with unexpected state %v present in SubConns map.", scd.rawConnectivityState)
559+
b.logger.Errorf("SubConn with unexpected state %v present in SubConns map.", sd.rawConnectivityState)
562560
return
563561

564562
}
@@ -753,8 +751,7 @@ func (b *pickfirstBalancer) endFirstPassIfPossibleLocked(lastErr error) {
753751
}
754752
// Connect() has been called on all the SubConns. The first pass can be
755753
// ended if all the SubConns have reported a failure.
756-
for _, v := range b.subConns.Values() {
757-
sd := v.(*scData)
754+
for _, sd := range b.subConns.Values() {
758755
if !sd.connectionFailedInFirstPass {
759756
return
760757
}
@@ -765,8 +762,7 @@ func (b *pickfirstBalancer) endFirstPassIfPossibleLocked(lastErr error) {
765762
Picker: &picker{err: lastErr},
766763
})
767764
// Start re-connecting all the SubConns that are already in IDLE.
768-
for _, v := range b.subConns.Values() {
769-
sd := v.(*scData)
765+
for _, sd := range b.subConns.Values() {
770766
if sd.rawConnectivityState == connectivity.Idle {
771767
sd.subConn.Connect()
772768
}

balancer/weightedroundrobin/balancer.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (bb) Build(cc balancer.ClientConn, bOpts balancer.BuildOptions) balancer.Ba
104104
ClientConn: cc,
105105
target: bOpts.Target.String(),
106106
metricsRecorder: cc.MetricsRecorder(),
107-
addressWeights: resolver.NewAddressMap(),
107+
addressWeights: resolver.NewAddressMapV2[*endpointWeight](),
108108
endpointToWeight: resolver.NewEndpointMap(),
109109
scToWeight: make(map[balancer.SubConn]*endpointWeight),
110110
}
@@ -156,7 +156,7 @@ func (bb) Name() string {
156156
// Caller must hold b.mu.
157157
func (b *wrrBalancer) updateEndpointsLocked(endpoints []resolver.Endpoint) {
158158
endpointSet := resolver.NewEndpointMap()
159-
addressSet := resolver.NewAddressMap()
159+
addressSet := resolver.NewAddressMapV2[*endpointWeight]()
160160
for _, endpoint := range endpoints {
161161
endpointSet.Set(endpoint, nil)
162162
for _, addr := range endpoint.Addresses {
@@ -214,7 +214,7 @@ type wrrBalancer struct {
214214
cfg *lbConfig // active config
215215
locality string
216216
stopPicker *grpcsync.Event
217-
addressWeights *resolver.AddressMap // addr -> endpointWeight
217+
addressWeights *resolver.AddressMapV2[*endpointWeight]
218218
endpointToWeight *resolver.EndpointMap // endpoint -> endpointWeight
219219
scToWeight map[balancer.SubConn]*endpointWeight
220220
}
@@ -329,7 +329,7 @@ func (b *wrrBalancer) NewSubConn(addrs []resolver.Address, opts balancer.NewSubC
329329
if err != nil {
330330
return nil, err
331331
}
332-
b.scToWeight[sc] = ewi.(*endpointWeight)
332+
b.scToWeight[sc] = ewi
333333
return sc, nil
334334
}
335335

resolver/map.go

+31-18
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,22 @@ import (
2424
"strings"
2525
)
2626

27-
type addressMapEntry struct {
27+
type addressMapEntry[T any] struct {
2828
addr Address
29-
value any
29+
value T
3030
}
3131

32-
// AddressMap is a map of addresses to arbitrary values taking into account
32+
// AddressMap is an AddressMapV2[any]. It will be deleted in an upcoming
33+
// release of grpc-go.
34+
//
35+
// Deprecated: use the generic AddressMapV2 type instead.
36+
type AddressMap = AddressMapV2[any]
37+
38+
// AddressMapV2 is a map of addresses to arbitrary values taking into account
3339
// Attributes. BalancerAttributes are ignored, as are Metadata and Type.
3440
// Multiple accesses may not be performed concurrently. Must be created via
3541
// NewAddressMap; do not construct directly.
36-
type AddressMap struct {
42+
type AddressMapV2[T any] struct {
3743
// The underlying map is keyed by an Address with fields that we don't care
3844
// about being set to their zero values. The only fields that we care about
3945
// are `Addr`, `ServerName` and `Attributes`. Since we need to be able to
@@ -47,23 +53,30 @@ type AddressMap struct {
4753
// The value type of the map contains a slice of addresses which match the key
4854
// in their `Addr` and `ServerName` fields and contain the corresponding value
4955
// associated with them.
50-
m map[Address]addressMapEntryList
56+
m map[Address]addressMapEntryList[T]
5157
}
5258

5359
func toMapKey(addr *Address) Address {
5460
return Address{Addr: addr.Addr, ServerName: addr.ServerName}
5561
}
5662

57-
type addressMapEntryList []*addressMapEntry
63+
type addressMapEntryList[T any] []*addressMapEntry[T]
5864

59-
// NewAddressMap creates a new AddressMap.
65+
// NewAddressMap creates a new AddressMapV2[any].
66+
//
67+
// Deprecated: use the generic NewAddressMapV2 constructor instead.
6068
func NewAddressMap() *AddressMap {
61-
return &AddressMap{m: make(map[Address]addressMapEntryList)}
69+
return NewAddressMapV2[any]()
70+
}
71+
72+
// NewAddressMapV2 creates a new AddressMapV2.
73+
func NewAddressMapV2[T any]() *AddressMapV2[T] {
74+
return &AddressMapV2[T]{m: make(map[Address]addressMapEntryList[T])}
6275
}
6376

6477
// find returns the index of addr in the addressMapEntry slice, or -1 if not
6578
// present.
66-
func (l addressMapEntryList) find(addr Address) int {
79+
func (l addressMapEntryList[T]) find(addr Address) int {
6780
for i, entry := range l {
6881
// Attributes are the only thing to match on here, since `Addr` and
6982
// `ServerName` are already equal.
@@ -75,28 +88,28 @@ func (l addressMapEntryList) find(addr Address) int {
7588
}
7689

7790
// Get returns the value for the address in the map, if present.
78-
func (a *AddressMap) Get(addr Address) (value any, ok bool) {
91+
func (a *AddressMapV2[T]) Get(addr Address) (value T, ok bool) {
7992
addrKey := toMapKey(&addr)
8093
entryList := a.m[addrKey]
8194
if entry := entryList.find(addr); entry != -1 {
8295
return entryList[entry].value, true
8396
}
84-
return nil, false
97+
return value, false
8598
}
8699

87100
// Set updates or adds the value to the address in the map.
88-
func (a *AddressMap) Set(addr Address, value any) {
101+
func (a *AddressMapV2[T]) Set(addr Address, value T) {
89102
addrKey := toMapKey(&addr)
90103
entryList := a.m[addrKey]
91104
if entry := entryList.find(addr); entry != -1 {
92105
entryList[entry].value = value
93106
return
94107
}
95-
a.m[addrKey] = append(entryList, &addressMapEntry{addr: addr, value: value})
108+
a.m[addrKey] = append(entryList, &addressMapEntry[T]{addr: addr, value: value})
96109
}
97110

98111
// Delete removes addr from the map.
99-
func (a *AddressMap) Delete(addr Address) {
112+
func (a *AddressMapV2[T]) Delete(addr Address) {
100113
addrKey := toMapKey(&addr)
101114
entryList := a.m[addrKey]
102115
entry := entryList.find(addr)
@@ -113,7 +126,7 @@ func (a *AddressMap) Delete(addr Address) {
113126
}
114127

115128
// Len returns the number of entries in the map.
116-
func (a *AddressMap) Len() int {
129+
func (a *AddressMapV2[T]) Len() int {
117130
ret := 0
118131
for _, entryList := range a.m {
119132
ret += len(entryList)
@@ -122,7 +135,7 @@ func (a *AddressMap) Len() int {
122135
}
123136

124137
// Keys returns a slice of all current map keys.
125-
func (a *AddressMap) Keys() []Address {
138+
func (a *AddressMapV2[T]) Keys() []Address {
126139
ret := make([]Address, 0, a.Len())
127140
for _, entryList := range a.m {
128141
for _, entry := range entryList {
@@ -133,8 +146,8 @@ func (a *AddressMap) Keys() []Address {
133146
}
134147

135148
// Values returns a slice of all current map values.
136-
func (a *AddressMap) Values() []any {
137-
ret := make([]any, 0, a.Len())
149+
func (a *AddressMapV2[T]) Values() []T {
150+
ret := make([]T, 0, a.Len())
138151
for _, entryList := range a.m {
139152
for _, entry := range entryList {
140153
ret = append(ret, entry.value)

resolver/map_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ var (
5252
)
5353

5454
func (s) TestAddressMap_Length(t *testing.T) {
55-
addrMap := NewAddressMap()
55+
addrMap := NewAddressMapV2[any]()
5656
if got := addrMap.Len(); got != 0 {
5757
t.Fatalf("addrMap.Len() = %v; want 0", got)
5858
}
@@ -72,7 +72,7 @@ func (s) TestAddressMap_Length(t *testing.T) {
7272
}
7373

7474
func (s) TestAddressMap_Get(t *testing.T) {
75-
addrMap := NewAddressMap()
75+
addrMap := NewAddressMapV2[any]()
7676
addrMap.Set(addr1, 1)
7777

7878
if got, ok := addrMap.Get(addr2); ok || got != nil {
@@ -109,7 +109,7 @@ func (s) TestAddressMap_Get(t *testing.T) {
109109
}
110110

111111
func (s) TestAddressMap_Delete(t *testing.T) {
112-
addrMap := NewAddressMap()
112+
addrMap := NewAddressMapV2[any]()
113113
addrMap.Set(addr1, 1)
114114
addrMap.Set(addr2, 2)
115115
if got, want := addrMap.Len(), 2; got != want {
@@ -132,7 +132,7 @@ func (s) TestAddressMap_Delete(t *testing.T) {
132132
}
133133

134134
func (s) TestAddressMap_Keys(t *testing.T) {
135-
addrMap := NewAddressMap()
135+
addrMap := NewAddressMapV2[any]()
136136
addrMap.Set(addr1, 1)
137137
addrMap.Set(addr2, 2)
138138
addrMap.Set(addr3, 3)
@@ -153,7 +153,7 @@ func (s) TestAddressMap_Keys(t *testing.T) {
153153
}
154154

155155
func (s) TestAddressMap_Values(t *testing.T) {
156-
addrMap := NewAddressMap()
156+
addrMap := NewAddressMapV2[any]()
157157
addrMap.Set(addr1, 1)
158158
addrMap.Set(addr2, 2)
159159
addrMap.Set(addr3, 3)

0 commit comments

Comments
 (0)