gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/benchmark/worker/main.go (about)

     1  /*
     2   *
     3   * Copyright 2016 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  // Binary worker implements the benchmark worker that can turn into a benchmark
    20  // client or server.
    21  package main
    22  
    23  import (
    24  	"context"
    25  	"flag"
    26  	"fmt"
    27  	"io"
    28  	"net"
    29  	"runtime"
    30  	"strconv"
    31  	"time"
    32  
    33  	_ "gitee.com/ks-custle/core-gm/gmhttp/pprof"
    34  
    35  	http "gitee.com/ks-custle/core-gm/gmhttp"
    36  
    37  	grpc "gitee.com/ks-custle/core-gm/grpc"
    38  	"gitee.com/ks-custle/core-gm/grpc/codes"
    39  	"gitee.com/ks-custle/core-gm/grpc/grpclog"
    40  	"gitee.com/ks-custle/core-gm/grpc/status"
    41  
    42  	testgrpc "gitee.com/ks-custle/core-gm/grpc/interop/grpc_testing"
    43  	testpb "gitee.com/ks-custle/core-gm/grpc/interop/grpc_testing"
    44  )
    45  
    46  var (
    47  	driverPort    = flag.Int("driver_port", 10000, "port for communication with driver")
    48  	serverPort    = flag.Int("server_port", 0, "port for benchmark server if not specified by server config message")
    49  	pprofPort     = flag.Int("pprof_port", -1, "Port for pprof debug server to listen on. Pprof server doesn't start if unset")
    50  	blockProfRate = flag.Int("block_prof_rate", 0, "fraction of goroutine blocking events to report in blocking profile")
    51  
    52  	logger = grpclog.Component("benchmark")
    53  )
    54  
    55  type byteBufCodec struct {
    56  }
    57  
    58  func (byteBufCodec) Marshal(v interface{}) ([]byte, error) {
    59  	b, ok := v.(*[]byte)
    60  	if !ok {
    61  		return nil, fmt.Errorf("failed to marshal: %v is not type of *[]byte", v)
    62  	}
    63  	return *b, nil
    64  }
    65  
    66  func (byteBufCodec) Unmarshal(data []byte, v interface{}) error {
    67  	b, ok := v.(*[]byte)
    68  	if !ok {
    69  		return fmt.Errorf("failed to marshal: %v is not type of *[]byte", v)
    70  	}
    71  	*b = data
    72  	return nil
    73  }
    74  
    75  func (byteBufCodec) String() string {
    76  	return "bytebuffer"
    77  }
    78  
    79  // workerServer implements WorkerService rpc handlers.
    80  // It can create benchmarkServer or benchmarkClient on demand.
    81  type workerServer struct {
    82  	testgrpc.UnimplementedWorkerServiceServer
    83  	stop       chan<- bool
    84  	serverPort int
    85  }
    86  
    87  func (s *workerServer) RunServer(stream testgrpc.WorkerService_RunServerServer) error {
    88  	var bs *benchmarkServer
    89  	defer func() {
    90  		// Close benchmark server when stream ends.
    91  		logger.Infof("closing benchmark server")
    92  		if bs != nil {
    93  			bs.closeFunc()
    94  		}
    95  	}()
    96  	for {
    97  		in, err := stream.Recv()
    98  		if err == io.EOF {
    99  			return nil
   100  		}
   101  		if err != nil {
   102  			return err
   103  		}
   104  
   105  		var out *testpb.ServerStatus
   106  		switch argtype := in.Argtype.(type) {
   107  		case *testpb.ServerArgs_Setup:
   108  			logger.Infof("server setup received:")
   109  			if bs != nil {
   110  				logger.Infof("server setup received when server already exists, closing the existing server")
   111  				bs.closeFunc()
   112  			}
   113  			bs, err = startBenchmarkServer(argtype.Setup, s.serverPort)
   114  			if err != nil {
   115  				return err
   116  			}
   117  			out = &testpb.ServerStatus{
   118  				Stats: bs.getStats(false),
   119  				Port:  int32(bs.port),
   120  				Cores: int32(bs.cores),
   121  			}
   122  
   123  		case *testpb.ServerArgs_Mark:
   124  			logger.Infof("server mark received:")
   125  			logger.Infof(" - %v", argtype)
   126  			if bs == nil {
   127  				return status.Error(codes.InvalidArgument, "server does not exist when mark received")
   128  			}
   129  			out = &testpb.ServerStatus{
   130  				Stats: bs.getStats(argtype.Mark.Reset_),
   131  				Port:  int32(bs.port),
   132  				Cores: int32(bs.cores),
   133  			}
   134  		}
   135  
   136  		if err := stream.Send(out); err != nil {
   137  			return err
   138  		}
   139  	}
   140  }
   141  
   142  func (s *workerServer) RunClient(stream testgrpc.WorkerService_RunClientServer) error {
   143  	var bc *benchmarkClient
   144  	defer func() {
   145  		// Shut down benchmark client when stream ends.
   146  		logger.Infof("shuting down benchmark client")
   147  		if bc != nil {
   148  			bc.shutdown()
   149  		}
   150  	}()
   151  	for {
   152  		in, err := stream.Recv()
   153  		if err == io.EOF {
   154  			return nil
   155  		}
   156  		if err != nil {
   157  			return err
   158  		}
   159  
   160  		var out *testpb.ClientStatus
   161  		switch t := in.Argtype.(type) {
   162  		case *testpb.ClientArgs_Setup:
   163  			logger.Infof("client setup received:")
   164  			if bc != nil {
   165  				logger.Infof("client setup received when client already exists, shuting down the existing client")
   166  				bc.shutdown()
   167  			}
   168  			bc, err = startBenchmarkClient(t.Setup)
   169  			if err != nil {
   170  				return err
   171  			}
   172  			out = &testpb.ClientStatus{
   173  				Stats: bc.getStats(false),
   174  			}
   175  
   176  		case *testpb.ClientArgs_Mark:
   177  			logger.Infof("client mark received:")
   178  			logger.Infof(" - %v", t)
   179  			if bc == nil {
   180  				return status.Error(codes.InvalidArgument, "client does not exist when mark received")
   181  			}
   182  			out = &testpb.ClientStatus{
   183  				Stats: bc.getStats(t.Mark.Reset_),
   184  			}
   185  		}
   186  
   187  		if err := stream.Send(out); err != nil {
   188  			return err
   189  		}
   190  	}
   191  }
   192  
   193  func (s *workerServer) CoreCount(ctx context.Context, in *testpb.CoreRequest) (*testpb.CoreResponse, error) {
   194  	logger.Infof("core count: %v", runtime.NumCPU())
   195  	return &testpb.CoreResponse{Cores: int32(runtime.NumCPU())}, nil
   196  }
   197  
   198  func (s *workerServer) QuitWorker(ctx context.Context, in *testpb.Void) (*testpb.Void, error) {
   199  	logger.Infof("quitting worker")
   200  	s.stop <- true
   201  	return &testpb.Void{}, nil
   202  }
   203  
   204  func main() {
   205  	grpc.EnableTracing = false
   206  
   207  	flag.Parse()
   208  	lis, err := net.Listen("tcp", ":"+strconv.Itoa(*driverPort))
   209  	if err != nil {
   210  		logger.Fatalf("failed to listen: %v", err)
   211  	}
   212  	logger.Infof("worker listening at port %v", *driverPort)
   213  
   214  	s := grpc.NewServer()
   215  	stop := make(chan bool)
   216  	testgrpc.RegisterWorkerServiceServer(s, &workerServer{
   217  		stop:       stop,
   218  		serverPort: *serverPort,
   219  	})
   220  
   221  	go func() {
   222  		<-stop
   223  		// Wait for 1 second before stopping the server to make sure the return value of QuitWorker is sent to client.
   224  		// TODO revise this once server graceful stop is supported in gRPC.
   225  		time.Sleep(time.Second)
   226  		s.Stop()
   227  	}()
   228  
   229  	runtime.SetBlockProfileRate(*blockProfRate)
   230  
   231  	if *pprofPort >= 0 {
   232  		go func() {
   233  			logger.Infoln("Starting pprof server on port " + strconv.Itoa(*pprofPort))
   234  			logger.Infoln(http.ListenAndServe("localhost:"+strconv.Itoa(*pprofPort), nil))
   235  		}()
   236  	}
   237  
   238  	s.Serve(lis)
   239  }