@@ -44,79 +44,107 @@ func (*pickfirstBuilder) Name() string {
44
44
}
45
45
46
46
type pickfirstBalancer struct {
47
- state connectivity.State
48
- cc balancer.ClientConn
49
- sc balancer.SubConn
47
+ state connectivity.State
48
+ cc balancer.ClientConn
49
+ subConn balancer.SubConn
50
50
}
51
51
52
52
func (b * pickfirstBalancer ) ResolverError (err error ) {
53
- switch b .state {
54
- case connectivity .TransientFailure , connectivity .Idle , connectivity .Connecting :
55
- // Set a failing picker if we don't have a good picker.
56
- b .cc .UpdateState (balancer.State {ConnectivityState : connectivity .TransientFailure ,
57
- Picker : & picker {err : fmt .Errorf ("name resolver error: %v" , err )},
58
- })
59
- }
60
53
if logger .V (2 ) {
61
54
logger .Infof ("pickfirstBalancer: ResolverError called with error %v" , err )
62
55
}
56
+ if b .subConn == nil {
57
+ b .state = connectivity .TransientFailure
58
+ }
59
+
60
+ if b .state != connectivity .TransientFailure {
61
+ // The picker will not change since the balancer does not currently
62
+ // report an error.
63
+ return
64
+ }
65
+ b .cc .UpdateState (balancer.State {
66
+ ConnectivityState : connectivity .TransientFailure ,
67
+ Picker : & picker {err : fmt .Errorf ("name resolver error: %v" , err )},
68
+ })
63
69
}
64
70
65
- func (b * pickfirstBalancer ) UpdateClientConnState (cs balancer.ClientConnState ) error {
66
- if len (cs .ResolverState .Addresses ) == 0 {
71
+ func (b * pickfirstBalancer ) UpdateClientConnState (state balancer.ClientConnState ) error {
72
+ if len (state .ResolverState .Addresses ) == 0 {
73
+ // The resolver reported an empty address list. Treat it like an error by
74
+ // calling b.ResolverError.
75
+ if b .subConn != nil {
76
+ // Remove the old subConn. All addresses were removed, so it is no longer
77
+ // valid.
78
+ b .cc .RemoveSubConn (b .subConn )
79
+ b .subConn = nil
80
+ }
67
81
b .ResolverError (errors .New ("produced zero addresses" ))
68
82
return balancer .ErrBadResolverState
69
83
}
70
- if b .sc == nil {
71
- var err error
72
- b .sc , err = b .cc .NewSubConn (cs .ResolverState .Addresses , balancer.NewSubConnOptions {})
73
- if err != nil {
74
- if logger .V (2 ) {
75
- logger .Errorf ("pickfirstBalancer: failed to NewSubConn: %v" , err )
76
- }
77
- b .state = connectivity .TransientFailure
78
- b .cc .UpdateState (balancer.State {ConnectivityState : connectivity .TransientFailure ,
79
- Picker : & picker {err : fmt .Errorf ("error creating connection: %v" , err )},
80
- })
81
- return balancer .ErrBadResolverState
84
+
85
+ if b .subConn != nil {
86
+ b .cc .UpdateAddresses (b .subConn , state .ResolverState .Addresses )
87
+ return nil
88
+ }
89
+
90
+ subConn , err := b .cc .NewSubConn (state .ResolverState .Addresses , balancer.NewSubConnOptions {})
91
+ if err != nil {
92
+ if logger .V (2 ) {
93
+ logger .Errorf ("pickfirstBalancer: failed to NewSubConn: %v" , err )
82
94
}
83
- b .state = connectivity .Idle
84
- b .cc .UpdateState (balancer.State {ConnectivityState : connectivity . Idle , Picker : & picker { result : balancer. PickResult { SubConn : b . sc }}})
85
- b . sc . Connect ()
86
- } else {
87
- b . cc . UpdateAddresses ( b . sc , cs . ResolverState . Addresses )
88
- b . sc . Connect ()
95
+ b .state = connectivity .TransientFailure
96
+ b .cc .UpdateState (balancer.State {
97
+ ConnectivityState : connectivity . TransientFailure ,
98
+ Picker : & picker { err : fmt . Errorf ( "error creating connection: %v" , err )},
99
+ } )
100
+ return balancer . ErrBadResolverState
89
101
}
102
+ b .subConn = subConn
103
+ b .state = connectivity .Idle
104
+ b .cc .UpdateState (balancer.State {
105
+ ConnectivityState : connectivity .Idle ,
106
+ Picker : & picker {result : balancer.PickResult {SubConn : b .subConn }},
107
+ })
108
+ b .subConn .Connect ()
90
109
return nil
91
110
}
92
111
93
- func (b * pickfirstBalancer ) UpdateSubConnState (sc balancer.SubConn , s balancer.SubConnState ) {
112
+ func (b * pickfirstBalancer ) UpdateSubConnState (subConn balancer.SubConn , state balancer.SubConnState ) {
94
113
if logger .V (2 ) {
95
- logger .Infof ("pickfirstBalancer: UpdateSubConnState: %p, %v" , sc , s )
114
+ logger .Infof ("pickfirstBalancer: UpdateSubConnState: %p, %v" , subConn , state )
96
115
}
97
- if b .sc != sc {
116
+ if b .subConn != subConn {
98
117
if logger .V (2 ) {
99
- logger .Infof ("pickfirstBalancer: ignored state change because sc is not recognized" )
118
+ logger .Infof ("pickfirstBalancer: ignored state change because subConn is not recognized" )
100
119
}
101
120
return
102
121
}
103
- b .state = s .ConnectivityState
104
- if s .ConnectivityState == connectivity .Shutdown {
105
- b .sc = nil
122
+ b .state = state .ConnectivityState
123
+ if state .ConnectivityState == connectivity .Shutdown {
124
+ b .subConn = nil
106
125
return
107
126
}
108
127
109
- switch s .ConnectivityState {
128
+ switch state .ConnectivityState {
110
129
case connectivity .Ready :
111
- b .cc .UpdateState (balancer.State {ConnectivityState : s .ConnectivityState , Picker : & picker {result : balancer.PickResult {SubConn : sc }}})
130
+ b .cc .UpdateState (balancer.State {
131
+ ConnectivityState : state .ConnectivityState ,
132
+ Picker : & picker {result : balancer.PickResult {SubConn : subConn }},
133
+ })
112
134
case connectivity .Connecting :
113
- b .cc .UpdateState (balancer.State {ConnectivityState : s .ConnectivityState , Picker : & picker {err : balancer .ErrNoSubConnAvailable }})
135
+ b .cc .UpdateState (balancer.State {
136
+ ConnectivityState : state .ConnectivityState ,
137
+ Picker : & picker {err : balancer .ErrNoSubConnAvailable },
138
+ })
114
139
case connectivity .Idle :
115
- b .cc .UpdateState (balancer.State {ConnectivityState : s .ConnectivityState , Picker : & idlePicker {sc : sc }})
140
+ b .cc .UpdateState (balancer.State {
141
+ ConnectivityState : state .ConnectivityState ,
142
+ Picker : & idlePicker {subConn : subConn },
143
+ })
116
144
case connectivity .TransientFailure :
117
145
b .cc .UpdateState (balancer.State {
118
- ConnectivityState : s .ConnectivityState ,
119
- Picker : & picker {err : s .ConnectionError },
146
+ ConnectivityState : state .ConnectivityState ,
147
+ Picker : & picker {err : state .ConnectionError },
120
148
})
121
149
}
122
150
}
@@ -125,8 +153,8 @@ func (b *pickfirstBalancer) Close() {
125
153
}
126
154
127
155
func (b * pickfirstBalancer ) ExitIdle () {
128
- if b .sc != nil && b .state == connectivity .Idle {
129
- b .sc .Connect ()
156
+ if b .subConn != nil && b .state == connectivity .Idle {
157
+ b .subConn .Connect ()
130
158
}
131
159
}
132
160
@@ -135,18 +163,18 @@ type picker struct {
135
163
err error
136
164
}
137
165
138
- func (p * picker ) Pick (info balancer.PickInfo ) (balancer.PickResult , error ) {
166
+ func (p * picker ) Pick (balancer.PickInfo ) (balancer.PickResult , error ) {
139
167
return p .result , p .err
140
168
}
141
169
142
170
// idlePicker is used when the SubConn is IDLE and kicks the SubConn into
143
171
// CONNECTING when Pick is called.
144
172
type idlePicker struct {
145
- sc balancer.SubConn
173
+ subConn balancer.SubConn
146
174
}
147
175
148
- func (i * idlePicker ) Pick (info balancer.PickInfo ) (balancer.PickResult , error ) {
149
- i .sc .Connect ()
176
+ func (i * idlePicker ) Pick (balancer.PickInfo ) (balancer.PickResult , error ) {
177
+ i .subConn .Connect ()
150
178
return balancer.PickResult {}, balancer .ErrNoSubConnAvailable
151
179
}
152
180
0 commit comments