Repository: grpc/grpc-go
File: internal/transport/http2_client.go (Go)

Code before:
		rstCode: rstCode,
	}
	addBackStreamQuota := func() bool {
		t.streamQuota++
		if t.streamQuota > 0 && t.waitingStreams > 0 {
			select {
			case t.streamsQuotaAvailable <- struct{}{}:
			default:
			}
		}
		return true
	}
	t.controlBuf.executeAndPut(addBackStreamQuota, cleanup)
	// This will unblock write.
	close(s.done)
	if s.doneFunc != nil {
		s.doneFunc()
	}
}

// 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.
func (t *http2Client) Close(err error) {
	if err := t.conn.SetWriteDeadline(time.Now().Add(time.Second * 10)); err != nil {
		logger.Warningf("Failed to set write deadline on t.conn during Close(): %s", err)
	}
	// For background on the deadline value chosen here, see
	// https://github.com/grpc/grpc-go/issues/8425#issuecomment-3057938248 .
	if err := t.conn.SetReadDeadline(time.Now().Add(time.Second)); err != nil {
		logger.Warningf("Failed to set read deadline on t.conn during Close(): %s", err)
	}
	t.mu.Lock()
	// Make sure we only close once.
	if t.state == closing {
		t.mu.Unlock()
		return
	}
	if t.logger.V(logLevel) {
		t.logger.Infof("Closing: %v", err)
	}
	// Call t.onClose ASAP to prevent the client from attempting to create new
	// streams.
	if t.state != draining {
		t.onClose(GoAwayInvalid)
	}
	t.state = closing
	streams := t.activeStreams
	t.activeStreams = nil
	if t.kpDormant {
		// If the keepalive goroutine is blocked on this condition variable, we

Review comment (bug):
nit: We should not mention internal symbol names like `t.conn` in the logs. It may be confusing for users and the message may become inaccurate after refactoring. Instead, we can say something more general like `Failed to set write deadline while closing connection`.

Code after:
		rstCode: rstCode,
	}
	addBackStreamQuota := func() bool {
		t.streamQuota++
		if t.streamQuota > 0 && t.waitingStreams > 0 {
			select {
			case t.streamsQuotaAvailable <- struct{}{}:
			default:
			}
		}
		return true
	}
	t.controlBuf.executeAndPut(addBackStreamQuota, cleanup)
	// This will unblock write.
	close(s.done)
	if s.doneFunc != nil {
		s.doneFunc()
	}
}

// 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.
func (t *http2Client) Close(err error) {
	t.conn.SetWriteDeadline(time.Now().Add(time.Second * 10))
	// For background on the deadline value chosen here, see
	// https://github.com/grpc/grpc-go/issues/8425#issuecomment-3057938248 .
	t.conn.SetReadDeadline(time.Now().Add(time.Second))
	t.mu.Lock()
	// Make sure we only close once.
	if t.state == closing {
		t.mu.Unlock()
		return
	}
	if t.logger.V(logLevel) {
		t.logger.Infof("Closing: %v", err)
	}
	// Call t.onClose ASAP to prevent the client from attempting to create new
	// streams.
	if t.state != draining {
		t.onClose(GoAwayInvalid)
	}
	t.state = closing
	streams := t.activeStreams
	t.activeStreams = nil
	if t.kpDormant {
		// If the keepalive goroutine is blocked on this condition variable, we
		// should unblock it so that the goroutine eventually exits.
		t.kpDormancyCond.Signal()
	}
	// Append info about previous goaways if there were any, since this may be important