github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/transport/transport.go (about)

     1  /*
     2   *
     3   * Copyright 2014 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  // Package transport defines and implements message oriented communication
    20  // channel to complete various transactions (e.g., an RPC).  It is meant for
    21  // grpc-internal usage and is not intended to be imported directly by users.
    22  package transport
    23  
    24  import (
    25  	"bytes"
    26  	"context"
    27  	"errors"
    28  	"fmt"
    29  	"io"
    30  	"net"
    31  	"sync"
    32  	"sync/atomic"
    33  	"time"
    34  
    35  	"github.com/hxx258456/ccgo/grpc/codes"
    36  	"github.com/hxx258456/ccgo/grpc/credentials"
    37  	"github.com/hxx258456/ccgo/grpc/keepalive"
    38  	"github.com/hxx258456/ccgo/grpc/metadata"
    39  	"github.com/hxx258456/ccgo/grpc/resolver"
    40  	"github.com/hxx258456/ccgo/grpc/stats"
    41  	"github.com/hxx258456/ccgo/grpc/status"
    42  	"github.com/hxx258456/ccgo/grpc/tap"
    43  )
    44  
    45  const logLevel = 2
    46  
    47  type bufferPool struct {
    48  	pool sync.Pool
    49  }
    50  
    51  func newBufferPool() *bufferPool {
    52  	return &bufferPool{
    53  		pool: sync.Pool{
    54  			New: func() interface{} {
    55  				return new(bytes.Buffer)
    56  			},
    57  		},
    58  	}
    59  }
    60  
    61  func (p *bufferPool) get() *bytes.Buffer {
    62  	return p.pool.Get().(*bytes.Buffer)
    63  }
    64  
    65  func (p *bufferPool) put(b *bytes.Buffer) {
    66  	p.pool.Put(b)
    67  }
    68  
    69  // recvMsg represents the received msg from the transport. All transport
    70  // protocol specific info has been removed.
    71  type recvMsg struct {
    72  	buffer *bytes.Buffer
    73  	// nil: received some data
    74  	// io.EOF: stream is completed. data is nil.
    75  	// other non-nil error: transport failure. data is nil.
    76  	err error
    77  }
    78  
    79  // recvBuffer is an unbounded channel of recvMsg structs.
    80  //
    81  // Note: recvBuffer differs from buffer.Unbounded only in the fact that it
    82  // holds a channel of recvMsg structs instead of objects implementing "item"
    83  // interface. recvBuffer is written to much more often and using strict recvMsg
    84  // structs helps avoid allocation in "recvBuffer.put"
    85  type recvBuffer struct {
    86  	c       chan recvMsg
    87  	mu      sync.Mutex
    88  	backlog []recvMsg
    89  	err     error
    90  }
    91  
    92  func newRecvBuffer() *recvBuffer {
    93  	b := &recvBuffer{
    94  		c: make(chan recvMsg, 1),
    95  	}
    96  	return b
    97  }
    98  
    99  func (b *recvBuffer) put(r recvMsg) {
   100  	b.mu.Lock()
   101  	if b.err != nil {
   102  		b.mu.Unlock()
   103  		// An error had occurred earlier, don't accept more
   104  		// data or errors.
   105  		return
   106  	}
   107  	b.err = r.err
   108  	if len(b.backlog) == 0 {
   109  		select {
   110  		case b.c <- r:
   111  			b.mu.Unlock()
   112  			return
   113  		default:
   114  		}
   115  	}
   116  	b.backlog = append(b.backlog, r)
   117  	b.mu.Unlock()
   118  }
   119  
   120  func (b *recvBuffer) load() {
   121  	b.mu.Lock()
   122  	if len(b.backlog) > 0 {
   123  		select {
   124  		case b.c <- b.backlog[0]:
   125  			b.backlog[0] = recvMsg{}
   126  			b.backlog = b.backlog[1:]
   127  		default:
   128  		}
   129  	}
   130  	b.mu.Unlock()
   131  }
   132  
   133  // get returns the channel that receives a recvMsg in the buffer.
   134  //
   135  // Upon receipt of a recvMsg, the caller should call load to send another
   136  // recvMsg onto the channel if there is any.
   137  func (b *recvBuffer) get() <-chan recvMsg {
   138  	return b.c
   139  }
   140  
   141  // recvBufferReader implements io.Reader interface to read the data from
   142  // recvBuffer.
   143  type recvBufferReader struct {
   144  	closeStream func(error) // Closes the client transport stream with the given error and nil trailer metadata.
   145  	ctx         context.Context
   146  	ctxDone     <-chan struct{} // cache of ctx.Done() (for performance).
   147  	recv        *recvBuffer
   148  	last        *bytes.Buffer // Stores the remaining data in the previous calls.
   149  	err         error
   150  	freeBuffer  func(*bytes.Buffer)
   151  }
   152  
   153  // Read reads the next len(p) bytes from last. If last is drained, it tries to
   154  // read additional data from recv. It blocks if there no additional data available
   155  // in recv. If Read returns any non-nil error, it will continue to return that error.
   156  func (r *recvBufferReader) Read(p []byte) (n int, err error) {
   157  	if r.err != nil {
   158  		return 0, r.err
   159  	}
   160  	if r.last != nil {
   161  		// Read remaining data left in last call.
   162  		copied, _ := r.last.Read(p)
   163  		if r.last.Len() == 0 {
   164  			r.freeBuffer(r.last)
   165  			r.last = nil
   166  		}
   167  		return copied, nil
   168  	}
   169  	if r.closeStream != nil {
   170  		n, r.err = r.readClient(p)
   171  	} else {
   172  		n, r.err = r.read(p)
   173  	}
   174  	return n, r.err
   175  }
   176  
   177  func (r *recvBufferReader) read(p []byte) (n int, err error) {
   178  	select {
   179  	case <-r.ctxDone:
   180  		return 0, ContextErr(r.ctx.Err())
   181  	case m := <-r.recv.get():
   182  		return r.readAdditional(m, p)
   183  	}
   184  }
   185  
   186  func (r *recvBufferReader) readClient(p []byte) (n int, err error) {
   187  	// If the context is canceled, then closes the stream with nil metadata.
   188  	// closeStream writes its error parameter to r.recv as a recvMsg.
   189  	// r.readAdditional acts on that message and returns the necessary error.
   190  	select {
   191  	case <-r.ctxDone:
   192  		// Note that this adds the ctx error to the end of recv buffer, and
   193  		// reads from the head. This will delay the error until recv buffer is
   194  		// empty, thus will delay ctx cancellation in Recv().
   195  		//
   196  		// It's done this way to fix a race between ctx cancel and trailer. The
   197  		// race was, stream.Recv() may return ctx error if ctxDone wins the
   198  		// race, but stream.Trailer() may return a non-nil md because the stream
   199  		// was not marked as done when trailer is received. This closeStream
   200  		// call will mark stream as done, thus fix the race.
   201  		//
   202  		// TODO: delaying ctx error seems like a unnecessary side effect. What
   203  		// we really want is to mark the stream as done, and return ctx error
   204  		// faster.
   205  		r.closeStream(ContextErr(r.ctx.Err()))
   206  		m := <-r.recv.get()
   207  		return r.readAdditional(m, p)
   208  	case m := <-r.recv.get():
   209  		return r.readAdditional(m, p)
   210  	}
   211  }
   212  
   213  func (r *recvBufferReader) readAdditional(m recvMsg, p []byte) (n int, err error) {
   214  	r.recv.load()
   215  	if m.err != nil {
   216  		return 0, m.err
   217  	}
   218  	copied, _ := m.buffer.Read(p)
   219  	if m.buffer.Len() == 0 {
   220  		r.freeBuffer(m.buffer)
   221  		r.last = nil
   222  	} else {
   223  		r.last = m.buffer
   224  	}
   225  	return copied, nil
   226  }
   227  
   228  type streamState uint32
   229  
   230  const (
   231  	streamActive    streamState = iota
   232  	streamWriteDone             // EndStream sent
   233  	streamReadDone              // EndStream received
   234  	streamDone                  // the entire stream is finished.
   235  )
   236  
   237  // Stream represents an RPC in the transport layer.
   238  type Stream struct {
   239  	id           uint32
   240  	st           ServerTransport    // nil for client side Stream
   241  	ct           *http2Client       // nil for server side Stream
   242  	ctx          context.Context    // the associated context of the stream
   243  	cancel       context.CancelFunc // always nil for client side Stream
   244  	done         chan struct{}      // closed at the end of stream to unblock writers. On the client side.
   245  	doneFunc     func()             // invoked at the end of stream on client side.
   246  	ctxDone      <-chan struct{}    // same as done chan but for server side. Cache of ctx.Done() (for performance)
   247  	method       string             // the associated RPC method of the stream
   248  	recvCompress string
   249  	sendCompress string
   250  	buf          *recvBuffer
   251  	trReader     io.Reader
   252  	fc           *inFlow
   253  	wq           *writeQuota
   254  
   255  	// Callback to state application's intentions to read data. This
   256  	// is used to adjust flow control, if needed.
   257  	requestRead func(int)
   258  
   259  	headerChan       chan struct{} // closed to indicate the end of header metadata.
   260  	headerChanClosed uint32        // set when headerChan is closed. Used to avoid closing headerChan multiple times.
   261  	// headerValid indicates whether a valid header was received.  Only
   262  	// meaningful after headerChan is closed (always call waitOnHeader() before
   263  	// reading its value).  Not valid on server side.
   264  	headerValid bool
   265  
   266  	// hdrMu protects header and trailer metadata on the server-side.
   267  	hdrMu sync.Mutex
   268  	// On client side, header keeps the received header metadata.
   269  	//
   270  	// On server side, header keeps the header set by SetHeader(). The complete
   271  	// header will merged into this after t.WriteHeader() is called.
   272  	header  metadata.MD
   273  	trailer metadata.MD // the key-value map of trailer metadata.
   274  
   275  	noHeaders bool // set if the client never received headers (set only after the stream is done).
   276  
   277  	// On the server-side, headerSent is atomically set to 1 when the headers are sent out.
   278  	headerSent uint32
   279  
   280  	state streamState
   281  
   282  	// On client-side it is the status error received from the server.
   283  	// On server-side it is unused.
   284  	status *status.Status
   285  
   286  	bytesReceived uint32 // indicates whether any bytes have been received on this stream
   287  	unprocessed   uint32 // set if the server sends a refused stream or GOAWAY including this stream
   288  
   289  	// contentSubtype is the content-subtype for requests.
   290  	// this must be lowercase or the behavior is undefined.
   291  	contentSubtype string
   292  }
   293  
   294  // isHeaderSent is only valid on the server-side.
   295  func (s *Stream) isHeaderSent() bool {
   296  	return atomic.LoadUint32(&s.headerSent) == 1
   297  }
   298  
   299  // updateHeaderSent updates headerSent and returns true
   300  // if it was alreay set. It is valid only on server-side.
   301  func (s *Stream) updateHeaderSent() bool {
   302  	return atomic.SwapUint32(&s.headerSent, 1) == 1
   303  }
   304  
   305  func (s *Stream) swapState(st streamState) streamState {
   306  	return streamState(atomic.SwapUint32((*uint32)(&s.state), uint32(st)))
   307  }
   308  
   309  func (s *Stream) compareAndSwapState(oldState, newState streamState) bool {
   310  	return atomic.CompareAndSwapUint32((*uint32)(&s.state), uint32(oldState), uint32(newState))
   311  }
   312  
   313  func (s *Stream) getState() streamState {
   314  	return streamState(atomic.LoadUint32((*uint32)(&s.state)))
   315  }
   316  
   317  func (s *Stream) waitOnHeader() {
   318  	if s.headerChan == nil {
   319  		// On the server headerChan is always nil since a stream originates
   320  		// only after having received headers.
   321  		return
   322  	}
   323  	select {
   324  	case <-s.ctx.Done():
   325  		// Close the stream to prevent headers/trailers from changing after
   326  		// this function returns.
   327  		s.ct.CloseStream(s, ContextErr(s.ctx.Err()))
   328  		// headerChan could possibly not be closed yet if closeStream raced
   329  		// with operateHeaders; wait until it is closed explicitly here.
   330  		<-s.headerChan
   331  	case <-s.headerChan:
   332  	}
   333  }
   334  
   335  // RecvCompress returns the compression algorithm applied to the inbound
   336  // message. It is empty string if there is no compression applied.
   337  func (s *Stream) RecvCompress() string {
   338  	s.waitOnHeader()
   339  	return s.recvCompress
   340  }
   341  
   342  // SetSendCompress sets the compression algorithm to the stream.
   343  func (s *Stream) SetSendCompress(str string) {
   344  	s.sendCompress = str
   345  }
   346  
   347  // Done returns a channel which is closed when it receives the final status
   348  // from the server.
   349  func (s *Stream) Done() <-chan struct{} {
   350  	return s.done
   351  }
   352  
   353  // Header returns the header metadata of the stream.
   354  //
   355  // On client side, it acquires the key-value pairs of header metadata once it is
   356  // available. It blocks until i) the metadata is ready or ii) there is no header
   357  // metadata or iii) the stream is canceled/expired.
   358  //
   359  // On server side, it returns the out header after t.WriteHeader is called.  It
   360  // does not block and must not be called until after WriteHeader.
   361  func (s *Stream) Header() (metadata.MD, error) {
   362  	if s.headerChan == nil {
   363  		// On server side, return the header in stream. It will be the out
   364  		// header after t.WriteHeader is called.
   365  		return s.header.Copy(), nil
   366  	}
   367  	s.waitOnHeader()
   368  	if !s.headerValid {
   369  		return nil, s.status.Err()
   370  	}
   371  	return s.header.Copy(), nil
   372  }
   373  
   374  // TrailersOnly blocks until a header or trailers-only frame is received and
   375  // then returns true if the stream was trailers-only.  If the stream ends
   376  // before headers are received, returns true, nil.  Client-side only.
   377  func (s *Stream) TrailersOnly() bool {
   378  	s.waitOnHeader()
   379  	return s.noHeaders
   380  }
   381  
   382  // Trailer returns the cached trailer metedata. Note that if it is not called
   383  // after the entire stream is done, it could return an empty MD. Client
   384  // side only.
   385  // It can be safely read only after stream has ended that is either read
   386  // or write have returned io.EOF.
   387  func (s *Stream) Trailer() metadata.MD {
   388  	c := s.trailer.Copy()
   389  	return c
   390  }
   391  
   392  // ContentSubtype returns the content-subtype for a request. For example, a
   393  // content-subtype of "proto" will result in a content-type of
   394  // "application/grpc+proto". This will always be lowercase.  See
   395  // https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for
   396  // more details.
   397  func (s *Stream) ContentSubtype() string {
   398  	return s.contentSubtype
   399  }
   400  
   401  // Context returns the context of the stream.
   402  func (s *Stream) Context() context.Context {
   403  	return s.ctx
   404  }
   405  
   406  // Method returns the method for the stream.
   407  func (s *Stream) Method() string {
   408  	return s.method
   409  }
   410  
   411  // Status returns the status received from the server.
   412  // Status can be read safely only after the stream has ended,
   413  // that is, after Done() is closed.
   414  func (s *Stream) Status() *status.Status {
   415  	return s.status
   416  }
   417  
   418  // SetHeader sets the header metadata. This can be called multiple times.
   419  // Server side only.
   420  // This should not be called in parallel to other data writes.
   421  func (s *Stream) SetHeader(md metadata.MD) error {
   422  	if md.Len() == 0 {
   423  		return nil
   424  	}
   425  	if s.isHeaderSent() || s.getState() == streamDone {
   426  		return ErrIllegalHeaderWrite
   427  	}
   428  	s.hdrMu.Lock()
   429  	s.header = metadata.Join(s.header, md)
   430  	s.hdrMu.Unlock()
   431  	return nil
   432  }
   433  
   434  // SendHeader sends the given header metadata. The given metadata is
   435  // combined with any metadata set by previous calls to SetHeader and
   436  // then written to the transport stream.
   437  func (s *Stream) SendHeader(md metadata.MD) error {
   438  	return s.st.WriteHeader(s, md)
   439  }
   440  
   441  // SetTrailer sets the trailer metadata which will be sent with the RPC status
   442  // by the server. This can be called multiple times. Server side only.
   443  // This should not be called parallel to other data writes.
   444  func (s *Stream) SetTrailer(md metadata.MD) error {
   445  	if md.Len() == 0 {
   446  		return nil
   447  	}
   448  	if s.getState() == streamDone {
   449  		return ErrIllegalHeaderWrite
   450  	}
   451  	s.hdrMu.Lock()
   452  	s.trailer = metadata.Join(s.trailer, md)
   453  	s.hdrMu.Unlock()
   454  	return nil
   455  }
   456  
   457  func (s *Stream) write(m recvMsg) {
   458  	s.buf.put(m)
   459  }
   460  
   461  // Read reads all p bytes from the wire for this stream.
   462  func (s *Stream) Read(p []byte) (n int, err error) {
   463  	// Don't request a read if there was an error earlier
   464  	if er := s.trReader.(*transportReader).er; er != nil {
   465  		return 0, er
   466  	}
   467  	s.requestRead(len(p))
   468  	return io.ReadFull(s.trReader, p)
   469  }
   470  
   471  // tranportReader reads all the data available for this Stream from the transport and
   472  // passes them into the decoder, which converts them into a gRPC message stream.
   473  // The error is io.EOF when the stream is done or another non-nil error if
   474  // the stream broke.
   475  type transportReader struct {
   476  	reader io.Reader
   477  	// The handler to control the window update procedure for both this
   478  	// particular stream and the associated transport.
   479  	windowHandler func(int)
   480  	er            error
   481  }
   482  
   483  func (t *transportReader) Read(p []byte) (n int, err error) {
   484  	n, err = t.reader.Read(p)
   485  	if err != nil {
   486  		t.er = err
   487  		return
   488  	}
   489  	t.windowHandler(n)
   490  	return
   491  }
   492  
   493  // BytesReceived indicates whether any bytes have been received on this stream.
   494  func (s *Stream) BytesReceived() bool {
   495  	return atomic.LoadUint32(&s.bytesReceived) == 1
   496  }
   497  
   498  // Unprocessed indicates whether the server did not process this stream --
   499  // i.e. it sent a refused stream or GOAWAY including this stream ID.
   500  func (s *Stream) Unprocessed() bool {
   501  	return atomic.LoadUint32(&s.unprocessed) == 1
   502  }
   503  
   504  // GoString is implemented by Stream so context.String() won't
   505  // race when printing %#v.
   506  func (s *Stream) GoString() string {
   507  	return fmt.Sprintf("<stream: %p, %v>", s, s.method)
   508  }
   509  
   510  // state of transport
   511  type transportState int
   512  
   513  const (
   514  	reachable transportState = iota
   515  	closing
   516  	draining
   517  )
   518  
   519  // ServerConfig consists of all the configurations to establish a server transport.
   520  type ServerConfig struct {
   521  	MaxStreams            uint32
   522  	ConnectionTimeout     time.Duration
   523  	Credentials           credentials.TransportCredentials
   524  	InTapHandle           tap.ServerInHandle
   525  	StatsHandler          stats.Handler
   526  	KeepaliveParams       keepalive.ServerParameters
   527  	KeepalivePolicy       keepalive.EnforcementPolicy
   528  	InitialWindowSize     int32
   529  	InitialConnWindowSize int32
   530  	WriteBufferSize       int
   531  	ReadBufferSize        int
   532  	ChannelzParentID      int64
   533  	MaxHeaderListSize     *uint32
   534  	HeaderTableSize       *uint32
   535  }
   536  
   537  // ConnectOptions covers all relevant options for communicating with the server.
   538  type ConnectOptions struct {
   539  	// UserAgent is the application user agent.
   540  	UserAgent string
   541  	// Dialer specifies how to dial a network address.
   542  	Dialer func(context.Context, string) (net.Conn, error)
   543  	// FailOnNonTempDialError specifies if gRPC fails on non-temporary dial errors.
   544  	FailOnNonTempDialError bool
   545  	// PerRPCCredentials stores the PerRPCCredentials required to issue RPCs.
   546  	PerRPCCredentials []credentials.PerRPCCredentials
   547  	// TransportCredentials stores the Authenticator required to setup a client
   548  	// connection. Only one of TransportCredentials and CredsBundle is non-nil.
   549  	TransportCredentials credentials.TransportCredentials
   550  	// CredsBundle is the credentials bundle to be used. Only one of
   551  	// TransportCredentials and CredsBundle is non-nil.
   552  	CredsBundle credentials.Bundle
   553  	// KeepaliveParams stores the keepalive parameters.
   554  	KeepaliveParams keepalive.ClientParameters
   555  	// StatsHandler stores the handler for stats.
   556  	StatsHandler stats.Handler
   557  	// InitialWindowSize sets the initial window size for a stream.
   558  	InitialWindowSize int32
   559  	// InitialConnWindowSize sets the initial window size for a connection.
   560  	InitialConnWindowSize int32
   561  	// WriteBufferSize sets the size of write buffer which in turn determines how much data can be batched before it's written on the wire.
   562  	WriteBufferSize int
   563  	// ReadBufferSize sets the size of read buffer, which in turn determines how much data can be read at most for one read syscall.
   564  	ReadBufferSize int
   565  	// ChannelzParentID sets the addrConn id which initiate the creation of this client transport.
   566  	ChannelzParentID int64
   567  	// MaxHeaderListSize sets the max (uncompressed) size of header list that is prepared to be received.
   568  	MaxHeaderListSize *uint32
   569  	// UseProxy specifies if a proxy should be used.
   570  	UseProxy bool
   571  }
   572  
   573  // NewClientTransport establishes the transport with the required ConnectOptions
   574  // and returns it to the caller.
   575  func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) {
   576  	return newHTTP2Client(connectCtx, ctx, addr, opts, onPrefaceReceipt, onGoAway, onClose)
   577  }
   578  
   579  // Options provides additional hints and information for message
   580  // transmission.
   581  type Options struct {
   582  	// Last indicates whether this write is the last piece for
   583  	// this stream.
   584  	Last bool
   585  }
   586  
   587  // CallHdr carries the information of a particular RPC.
   588  type CallHdr struct {
   589  	// Host specifies the peer's host.
   590  	Host string
   591  
   592  	// Method specifies the operation to perform.
   593  	Method string
   594  
   595  	// SendCompress specifies the compression algorithm applied on
   596  	// outbound message.
   597  	SendCompress string
   598  
   599  	// Creds specifies credentials.PerRPCCredentials for a call.
   600  	Creds credentials.PerRPCCredentials
   601  
   602  	// ContentSubtype specifies the content-subtype for a request. For example, a
   603  	// content-subtype of "proto" will result in a content-type of
   604  	// "application/grpc+proto". The value of ContentSubtype must be all
   605  	// lowercase, otherwise the behavior is undefined. See
   606  	// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
   607  	// for more details.
   608  	ContentSubtype string
   609  
   610  	PreviousAttempts int // value of grpc-previous-rpc-attempts header to set
   611  
   612  	DoneFunc func() // called when the stream is finished
   613  }
   614  
   615  // ClientTransport is the common interface for all gRPC client-side transport
   616  // implementations.
   617  type ClientTransport interface {
   618  	// Close tears down this transport. Once it returns, the transport
   619  	// should not be accessed any more. The caller must make sure this
   620  	// is called only once.
   621  	Close(err error)
   622  
   623  	// GracefulClose starts to tear down the transport: the transport will stop
   624  	// accepting new RPCs and NewStream will return error. Once all streams are
   625  	// finished, the transport will close.
   626  	//
   627  	// It does not block.
   628  	GracefulClose()
   629  
   630  	// Write sends the data for the given stream. A nil stream indicates
   631  	// the write is to be performed on the transport as a whole.
   632  	Write(s *Stream, hdr []byte, data []byte, opts *Options) error
   633  
   634  	// NewStream creates a Stream for an RPC.
   635  	NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error)
   636  
   637  	// CloseStream clears the footprint of a stream when the stream is
   638  	// not needed any more. The err indicates the error incurred when
   639  	// CloseStream is called. Must be called when a stream is finished
   640  	// unless the associated transport is closing.
   641  	CloseStream(stream *Stream, err error)
   642  
   643  	// Error returns a channel that is closed when some I/O error
   644  	// happens. Typically the caller should have a goroutine to monitor
   645  	// this in order to take action (e.g., close the current transport
   646  	// and create a new one) in error case. It should not return nil
   647  	// once the transport is initiated.
   648  	Error() <-chan struct{}
   649  
   650  	// GoAway returns a channel that is closed when ClientTransport
   651  	// receives the draining signal from the server (e.g., GOAWAY frame in
   652  	// HTTP/2).
   653  	GoAway() <-chan struct{}
   654  
   655  	// GetGoAwayReason returns the reason why GoAway frame was received, along
   656  	// with a human readable string with debug info.
   657  	GetGoAwayReason() (GoAwayReason, string)
   658  
   659  	// RemoteAddr returns the remote network address.
   660  	RemoteAddr() net.Addr
   661  
   662  	// IncrMsgSent increments the number of message sent through this transport.
   663  	IncrMsgSent()
   664  
   665  	// IncrMsgRecv increments the number of message received through this transport.
   666  	IncrMsgRecv()
   667  }
   668  
   669  // ServerTransport is the common interface for all gRPC server-side transport
   670  // implementations.
   671  //
   672  // Methods may be called concurrently from multiple goroutines, but
   673  // Write methods for a given Stream will be called serially.
   674  type ServerTransport interface {
   675  	// HandleStreams receives incoming streams using the given handler.
   676  	HandleStreams(func(*Stream), func(context.Context, string) context.Context)
   677  
   678  	// WriteHeader sends the header metadata for the given stream.
   679  	// WriteHeader may not be called on all streams.
   680  	WriteHeader(s *Stream, md metadata.MD) error
   681  
   682  	// Write sends the data for the given stream.
   683  	// Write may not be called on all streams.
   684  	Write(s *Stream, hdr []byte, data []byte, opts *Options) error
   685  
   686  	// WriteStatus sends the status of a stream to the client.  WriteStatus is
   687  	// the final call made on a stream and always occurs.
   688  	WriteStatus(s *Stream, st *status.Status) error
   689  
   690  	// Close tears down the transport. Once it is called, the transport
   691  	// should not be accessed any more. All the pending streams and their
   692  	// handlers will be terminated asynchronously.
   693  	Close()
   694  
   695  	// RemoteAddr returns the remote network address.
   696  	RemoteAddr() net.Addr
   697  
   698  	// Drain notifies the client this ServerTransport stops accepting new RPCs.
   699  	Drain()
   700  
   701  	// IncrMsgSent increments the number of message sent through this transport.
   702  	IncrMsgSent()
   703  
   704  	// IncrMsgRecv increments the number of message received through this transport.
   705  	IncrMsgRecv()
   706  }
   707  
   708  // connectionErrorf creates an ConnectionError with the specified error description.
   709  func connectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
   710  	return ConnectionError{
   711  		Desc: fmt.Sprintf(format, a...),
   712  		temp: temp,
   713  		err:  e,
   714  	}
   715  }
   716  
   717  // ConnectionError is an error that results in the termination of the
   718  // entire connection and the retry of all the active streams.
   719  type ConnectionError struct {
   720  	Desc string
   721  	temp bool
   722  	err  error
   723  }
   724  
   725  func (e ConnectionError) Error() string {
   726  	return fmt.Sprintf("connection error: desc = %q", e.Desc)
   727  }
   728  
   729  // Temporary indicates if this connection error is temporary or fatal.
   730  func (e ConnectionError) Temporary() bool {
   731  	return e.temp
   732  }
   733  
   734  // Origin returns the original error of this connection error.
   735  func (e ConnectionError) Origin() error {
   736  	// Never return nil error here.
   737  	// If the original error is nil, return itself.
   738  	if e.err == nil {
   739  		return e
   740  	}
   741  	return e.err
   742  }
   743  
   744  var (
   745  	// ErrConnClosing indicates that the transport is closing.
   746  	ErrConnClosing = connectionErrorf(true, nil, "transport is closing")
   747  	// errStreamDrain indicates that the stream is rejected because the
   748  	// connection is draining. This could be caused by goaway or balancer
   749  	// removing the address.
   750  	errStreamDrain = status.Error(codes.Unavailable, "the connection is draining")
   751  	// errStreamDone is returned from write at the client side to indiacte application
   752  	// layer of an error.
   753  	errStreamDone = errors.New("the stream is done")
   754  	// StatusGoAway indicates that the server sent a GOAWAY that included this
   755  	// stream's ID in unprocessed RPCs.
   756  	statusGoAway = status.New(codes.Unavailable, "the stream is rejected because server is draining the connection")
   757  )
   758  
   759  // GoAwayReason contains the reason for the GoAway frame received.
   760  type GoAwayReason uint8
   761  
   762  const (
   763  	// GoAwayInvalid indicates that no GoAway frame is received.
   764  	GoAwayInvalid GoAwayReason = 0
   765  	// GoAwayNoReason is the default value when GoAway frame is received.
   766  	GoAwayNoReason GoAwayReason = 1
   767  	// GoAwayTooManyPings indicates that a GoAway frame with
   768  	// ErrCodeEnhanceYourCalm was received and that the debug data said
   769  	// "too_many_pings".
   770  	GoAwayTooManyPings GoAwayReason = 2
   771  )
   772  
   773  // channelzData is used to store channelz related data for http2Client and http2Server.
   774  // These fields cannot be embedded in the original structs (e.g. http2Client), since to do atomic
   775  // operation on int64 variable on 32-bit machine, user is responsible to enforce memory alignment.
   776  // Here, by grouping those int64 fields inside a struct, we are enforcing the alignment.
   777  type channelzData struct {
   778  	kpCount int64
   779  	// The number of streams that have started, including already finished ones.
   780  	streamsStarted int64
   781  	// Client side: The number of streams that have ended successfully by receiving
   782  	// EoS bit set frame from server.
   783  	// Server side: The number of streams that have ended successfully by sending
   784  	// frame with EoS bit set.
   785  	streamsSucceeded int64
   786  	streamsFailed    int64
   787  	// lastStreamCreatedTime stores the timestamp that the last stream gets created. It is of int64 type
   788  	// instead of time.Time since it's more costly to atomically update time.Time variable than int64
   789  	// variable. The same goes for lastMsgSentTime and lastMsgRecvTime.
   790  	lastStreamCreatedTime int64
   791  	msgSent               int64
   792  	msgRecv               int64
   793  	lastMsgSentTime       int64
   794  	lastMsgRecvTime       int64
   795  }
   796  
   797  // ContextErr converts the error from context package into a status error.
   798  func ContextErr(err error) error {
   799  	switch err {
   800  	case context.DeadlineExceeded:
   801  		return status.Error(codes.DeadlineExceeded, err.Error())
   802  	case context.Canceled:
   803  		return status.Error(codes.Canceled, err.Error())
   804  	}
   805  	return status.Errorf(codes.Internal, "Unexpected error from context packet: %v", err)
   806  }