private void maybeUpdatePicker ( ) { List < RoundRobinEntry > pickList ; ConnectivityState state ; switch ( mode ) { case ROUND_ROBIN : pickList = new ArrayList <> ( backendList . size ( ) ) ; Status error = null ; boolean hasIdle = false ; for ( BackendEntry entry : backendList ) { Subchannel subchannel = entry . subchannel ; Attributes attrs = subchannel . getAttributes ( ) ; ConnectivityStateInfo stateInfo = attrs . get ( STATE_INFO ) . get ( ) ; if ( stateInfo . getState ( ) == READY ) { pickList . add ( entry ) ; } else if ( stateInfo . getState ( ) == TRANSIENT_FAILURE ) { error = stateInfo . getStatus ( ) ; } else if ( stateInfo . getState ( ) == IDLE ) { hasIdle = true ; } } if ( pickList . isEmpty ( ) ) { if ( error != null && ! hasIdle ) { pickList . add ( new ErrorEntry ( error ) ) ; state = TRANSIENT_FAILURE ; } else { pickList . add ( BUFFER_ENTRY ) ; state = CONNECTING ; } } else { state = READY ; } break ; case PICK_FIRST : if ( backendList . isEmpty ( ) ) { pickList = Collections . singletonList ( BUFFER_ENTRY ) ; // Have not received server addresses state = CONNECTING ; } else { checkState ( backendList . size ( ) == 1 , "Excessive backend entries: %s" , backendList ) ; BackendEntry onlyEntry = backendList . get ( 0 ) ; ConnectivityStateInfo stateInfo = onlyEntry . subchannel . getAttributes ( ) . get ( STATE_INFO ) . get ( ) ; state = stateInfo . getState ( ) ; switch ( state ) { case READY : pickList = Collections . < RoundRobinEntry > singletonList ( onlyEntry ) ; break ; case TRANSIENT_FAILURE : pickList = Collections . < RoundRobinEntry > singletonList ( new ErrorEntry ( stateInfo . getStatus ( ) ) ) ; break ; case CONNECTING : pickList = Collections . singletonList ( BUFFER_ENTRY ) ; break ; default : pickList = Collections . < RoundRobinEntry > singletonList ( new IdleSubchannelEntry ( onlyEntry . subchannel ) ) ; } } break ; default : throw new AssertionError ( "Missing case for " + mode ) ; } maybeUpdatePicker ( state , new RoundRobinPicker ( dropList , pickList ) ) ; }
Make and use a picker out of the current lists and the states of subchannels if they have changed since the last picker created .