grpc: close underlying transport when subConn is closed when in connecting state (#4751)

This commit is contained in:
Easwar Swaminathan
2021-09-10 14:08:26 -07:00
committed by GitHub
parent 4e07a14b4e
commit 7f560ef4c5

View File

@ -1322,17 +1322,19 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
}
select {
case <-time.After(time.Until(connectDeadline)):
case <-connectCtx.Done():
// We didn't get the preface in time.
err := fmt.Errorf("failed to receive server preface within timeout")
newTr.Close(err)
channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: %v", addr, err)
return err
newTr.Close(transport.ErrConnClosing)
if connectCtx.Err() == context.DeadlineExceeded {
err := errors.New("failed to receive server preface within timeout")
channelz.Warningf(logger, ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: %v", addr, err)
return err
}
return nil
case <-prefaceReceived.Done():
// We got the preface - huzzah! things are good.
ac.mu.Lock()
defer ac.mu.Unlock()
defer prefaceReceived.Fire()
if connClosed.HasFired() {
// onClose called first; go idle but do nothing else.
if ac.state != connectivity.Shutdown {
@ -1340,6 +1342,16 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
}
return nil
}
if ac.state == connectivity.Shutdown {
// This can happen if the subConn was removed while in `Connecting`
// state. tearDown() would have set the state to `Shutdown`, but
// would not have closed the transport since ac.transport would not
// been set at that point.
// We run this in a goroutine because newTr.Close() calls onClose()
// inline, which requires locking ac.mu.
go newTr.Close(transport.ErrConnClosing)
return nil
}
ac.curAddr = addr
ac.transport = newTr
hcStarted = true