@@ -43,7 +43,6 @@ import (
4343 "google.golang.org/grpc/internal"
4444 "google.golang.org/grpc/internal/binarylog"
4545 "google.golang.org/grpc/internal/channelz"
46- "google.golang.org/grpc/internal/grpcrand"
4746 "google.golang.org/grpc/internal/grpcsync"
4847 "google.golang.org/grpc/internal/grpcutil"
4948 "google.golang.org/grpc/internal/transport"
@@ -146,7 +145,7 @@ type Server struct {
146145 channelzID * channelz.Identifier
147146 czData * channelzData
148147
149- serverWorkerChannels [] chan * serverWorkerData
148+ serverWorkerChannel chan * serverWorkerData
150149}
151150
152151type serverOptions struct {
@@ -561,40 +560,38 @@ func NumStreamWorkers(numServerWorkers uint32) ServerOption {
561560const serverWorkerResetThreshold = 1 << 16
562561
563562// serverWorkers blocks on a *transport.Stream channel forever and waits for
564- // data to be fed by serveStreams. This allows different requests to be
563+ // data to be fed by serveStreams. This allows multiple requests to be
565564// processed by the same goroutine, removing the need for expensive stack
566565// re-allocations (see the runtime.morestack problem [1]).
567566//
568567// [1] https://github.com/golang/go/issues/18138
569- func (s * Server ) serverWorker (ch chan * serverWorkerData ) {
570- // To make sure all server workers don't reset at the same time, choose a
571- // random number of iterations before resetting.
572- threshold := serverWorkerResetThreshold + grpcrand .Intn (serverWorkerResetThreshold )
573- for completed := 0 ; completed < threshold ; completed ++ {
574- data , ok := <- ch
568+ func (s * Server ) serverWorker () {
569+ for completed := 0 ; completed < serverWorkerResetThreshold ; completed ++ {
570+ data , ok := <- s .serverWorkerChannel
575571 if ! ok {
576572 return
577573 }
578- s .handleStream (data .st , data .stream , s .traceInfo (data .st , data .stream ))
579- data .wg .Done ()
574+ s .handleSingleStream (data )
580575 }
581- go s .serverWorker (ch )
576+ go s .serverWorker ()
582577}
583578
584- // initServerWorkers creates worker goroutines and channels to process incoming
579+ func (s * Server ) handleSingleStream (data * serverWorkerData ) {
580+ defer data .wg .Done ()
581+ s .handleStream (data .st , data .stream , s .traceInfo (data .st , data .stream ))
582+ }
583+
584+ // initServerWorkers creates worker goroutines and a channel to process incoming
585585// connections to reduce the time spent overall on runtime.morestack.
586586func (s * Server ) initServerWorkers () {
587- s .serverWorkerChannels = make ([] chan * serverWorkerData , s . opts . numServerWorkers )
587+ s .serverWorkerChannel = make (chan * serverWorkerData )
588588 for i := uint32 (0 ); i < s .opts .numServerWorkers ; i ++ {
589- s .serverWorkerChannels [i ] = make (chan * serverWorkerData )
590- go s .serverWorker (s .serverWorkerChannels [i ])
589+ go s .serverWorker ()
591590 }
592591}
593592
594593func (s * Server ) stopServerWorkers () {
595- for i := uint32 (0 ); i < s .opts .numServerWorkers ; i ++ {
596- close (s .serverWorkerChannels [i ])
597- }
594+ close (s .serverWorkerChannel )
598595}
599596
600597// NewServer creates a gRPC server which has no service registered and has not
@@ -946,26 +943,21 @@ func (s *Server) serveStreams(st transport.ServerTransport) {
946943 defer st .Close (errors .New ("finished serving streams for the server transport" ))
947944 var wg sync.WaitGroup
948945
949- var roundRobinCounter uint32
950946 st .HandleStreams (func (stream * transport.Stream ) {
951947 wg .Add (1 )
952948 if s .opts .numServerWorkers > 0 {
953949 data := & serverWorkerData {st : st , wg : & wg , stream : stream }
954950 select {
955- case s .serverWorkerChannels [atomic .AddUint32 (& roundRobinCounter , 1 )% s .opts .numServerWorkers ] <- data :
951+ case s .serverWorkerChannel <- data :
952+ return
956953 default :
957954 // If all stream workers are busy, fallback to the default code path.
958- go func () {
959- s .handleStream (st , stream , s .traceInfo (st , stream ))
960- wg .Done ()
961- }()
962955 }
963- } else {
964- go func () {
965- defer wg .Done ()
966- s .handleStream (st , stream , s .traceInfo (st , stream ))
967- }()
968956 }
957+ go func () {
958+ defer wg .Done ()
959+ s .handleStream (st , stream , s .traceInfo (st , stream ))
960+ }()
969961 }, func (ctx context.Context , method string ) context.Context {
970962 if ! EnableTracing {
971963 return ctx
0 commit comments