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 }