regeneratePicker takes a snapshot of the balancer, and generates a picker from it. The picker - always returns ErrTransientFailure if the balancer is in TransientFailure, - does two layer roundrobin pick otherwise. Caller must hold lb.mu.
(resetDrop bool)
| 245 | // |
| 246 | // Caller must hold lb.mu. |
| 247 | func (lb *lbBalancer) regeneratePicker(resetDrop bool) { |
| 248 | if lb.state == connectivity.TransientFailure { |
| 249 | lb.picker = base.NewErrPicker(fmt.Errorf("all SubConns are in TransientFailure, last connection error: %v", lb.connErr)) |
| 250 | return |
| 251 | } |
| 252 | |
| 253 | if lb.state == connectivity.Connecting { |
| 254 | lb.picker = base.NewErrPicker(balancer.ErrNoSubConnAvailable) |
| 255 | return |
| 256 | } |
| 257 | |
| 258 | var readySCs []balancer.SubConn |
| 259 | if lb.usePickFirst { |
| 260 | for _, sc := range lb.subConns { |
| 261 | readySCs = append(readySCs, sc) |
| 262 | break |
| 263 | } |
| 264 | } else { |
| 265 | for _, a := range lb.backendAddrsWithoutMetadata { |
| 266 | if sc, ok := lb.subConns[a]; ok { |
| 267 | if st, ok := lb.scStates[sc]; ok && st == connectivity.Ready { |
| 268 | readySCs = append(readySCs, sc) |
| 269 | } |
| 270 | } |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | if len(readySCs) <= 0 { |
| 275 | // If there's no ready SubConns, always re-pick. This is to avoid drops |
| 276 | // unless at least one SubConn is ready. Otherwise we may drop more |
| 277 | // often than want because of drops + re-picks(which become re-drops). |
| 278 | // |
| 279 | // This doesn't seem to be necessary after the connecting check above. |
| 280 | // Kept for safety. |
| 281 | lb.picker = base.NewErrPicker(balancer.ErrNoSubConnAvailable) |
| 282 | return |
| 283 | } |
| 284 | if lb.inFallback { |
| 285 | lb.picker = newRRPicker(readySCs) |
| 286 | return |
| 287 | } |
| 288 | if resetDrop { |
| 289 | lb.picker = newLBPicker(lb.fullServerList, readySCs, lb.clientStats) |
| 290 | return |
| 291 | } |
| 292 | prevLBPicker, ok := lb.picker.(*lbPicker) |
| 293 | if !ok { |
| 294 | lb.picker = newLBPicker(lb.fullServerList, readySCs, lb.clientStats) |
| 295 | return |
| 296 | } |
| 297 | prevLBPicker.updateReadySCs(readySCs) |
| 298 | } |
| 299 | |
| 300 | // aggregateSubConnStats calculate the aggregated state of SubConns in |
| 301 | // lb.SubConns. These SubConns are subconns in use (when switching between |
no test coverage detected