MCPcopy
hub / github.com/grpc/grpc-go / Close

Method Close

internal/transport/http2_client.go:1010–1081  ·  view source on GitHub ↗

Close kicks off the shutdown process of the transport. This should be called only once on a transport. Once it is called, the transport should not be accessed anymore.

(err error)

Source from the content-addressed store, hash-verified

1008// only once on a transport. Once it is called, the transport should not be
1009// accessed anymore.
1010func (t *http2Client) Close(err error) {
1011 t.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
1012 // For background on the deadline value chosen here, see
1013 // https://github.com/grpc/grpc-go/issues/8425#issuecomment-3057938248 .
1014 t.conn.SetReadDeadline(time.Now().Add(time.Second))
1015 t.mu.Lock()
1016 // Make sure we only close once.
1017 if t.state == closing {
1018 t.mu.Unlock()
1019 return
1020 }
1021 if t.logger.V(logLevel) {
1022 t.logger.Infof("Closing: %v", err)
1023 }
1024 // Call t.onClose ASAP to prevent the client from attempting to create new
1025 // streams.
1026 if t.state != draining {
1027 t.onClose(GoAwayInfo{Reason: GoAwayInvalid, GoAwayCode: http2.ErrCodeNo, Err: err})
1028 }
1029 t.state = closing
1030 streams := t.activeStreams
1031 t.activeStreams = nil
1032 if t.kpDormant {
1033 // If the keepalive goroutine is blocked on this condition variable, we
1034 // should unblock it so that the goroutine eventually exits.
1035 t.kpDormancyCond.Signal()
1036 }
1037 // Append info about previous goaways if there were any, since this may be important
1038 // for understanding the root cause for this connection to be closed.
1039 goAwayDebugMessage := t.goAwayDebugMessage
1040 t.mu.Unlock()
1041
1042 // Per HTTP/2 spec, a GOAWAY frame must be sent before closing the
1043 // connection. See https://httpwg.org/specs/rfc7540.html#GOAWAY. It
1044 // also waits for loopyWriter to be closed with a timer to avoid the
1045 // long blocking in case the connection is blackholed, i.e. TCP is
1046 // just stuck.
1047 t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte("client transport shutdown"), closeConn: err})
1048 timer := time.NewTimer(goAwayLoopyWriterTimeout)
1049 defer timer.Stop()
1050 select {
1051 case <-t.writerDone: // success
1052 case <-timer.C:
1053 t.logger.Infof("Failed to write a GOAWAY frame as part of connection close after %s. Giving up and closing the transport.", goAwayLoopyWriterTimeout)
1054 }
1055 t.cancel()
1056 t.conn.Close()
1057 // Waits for the reader and keepalive goroutines to exit before returning to
1058 // ensure all resources are cleaned up before Close can return.
1059 <-t.readerDone
1060 if t.keepaliveEnabled {
1061 <-t.keepaliveDone
1062 }
1063 channelz.RemoveEntry(t.channelz.ID)
1064 var st *status.Status
1065 if len(goAwayDebugMessage) > 0 {
1066 st = status.Newf(codes.Unavailable, "closing transport due to: %v, received prior goaway: %v", err, goAwayDebugMessage)
1067 err = st.Err()

Callers 4

NewHTTP2ClientFunction · 0.95
GracefulCloseMethod · 0.95
readerMethod · 0.95
keepaliveMethod · 0.95

Calls 15

StopMethod · 0.95
ErrMethod · 0.95
closeStreamMethod · 0.95
RemoveEntryFunction · 0.92
NewfFunction · 0.92
NewFunction · 0.92
NowMethod · 0.80
NewTimerMethod · 0.80
cancelMethod · 0.80
AddMethod · 0.65
VMethod · 0.65
InfofMethod · 0.65

Tested by

no test coverage detected