@@ -1193,14 +1193,22 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error)
11931193 if ac .state == s {
11941194 return
11951195 }
1196+ if ac .state == connectivity .Ready {
1197+ // When leaving ready, re-create the ready channel.
1198+ ac .stateReadyChan = make (chan struct {})
1199+ }
1200+ if s == connectivity .Shutdown {
1201+ // Wake any producer waiting to create a stream on the transport.
1202+ close (ac .stateReadyChan )
1203+ }
11961204 ac .state = s
11971205 ac .channelz .ChannelMetrics .State .Store (& s )
11981206 if lastErr == nil {
11991207 channelz .Infof (logger , ac .channelz , "Subchannel Connectivity change to %v" , s )
12001208 } else {
12011209 channelz .Infof (logger , ac .channelz , "Subchannel Connectivity change to %v, last error: %s" , s , lastErr )
12021210 }
1203- ac .acbw .updateState (s , ac .curAddr , lastErr )
1211+ ac .acbw .updateState (s , ac .curAddr , lastErr , ac . stateReadyChan )
12041212}
12051213
12061214// adjustParams updates parameters used to create transports upon
@@ -1510,18 +1518,20 @@ func (ac *addrConn) getReadyTransport() transport.ClientTransport {
15101518func (ac * addrConn ) getTransport (ctx context.Context ) (transport.ClientTransport , error ) {
15111519 for ctx .Err () == nil {
15121520 ac .mu .Lock ()
1513- t , state , sc := ac .transport , ac .state , ac .stateReadyChan
1521+ t , state , readyChan := ac .transport , ac .state , ac .stateReadyChan
15141522 ac .mu .Unlock ()
1515- if state == connectivity .Ready {
1516- return t , nil
1517- }
15181523 if state == connectivity .Shutdown {
1524+ // Return an error immediately in only this case since a connection
1525+ // will never occur.
15191526 return nil , status .Errorf (codes .Unavailable , "SubConn shutting down" )
15201527 }
15211528
15221529 select {
15231530 case <- ctx .Done ():
1524- case <- sc :
1531+ case <- readyChan :
1532+ if state == connectivity .Ready {
1533+ return t , nil
1534+ }
15251535 }
15261536 }
15271537 return nil , status .FromContextError (ctx .Err ()).Err ()
0 commit comments