github.com/annwntech/go-micro/v2@v2.9.5/server/grpc/grpc.go (about)

     1  // Package grpc provides a grpc server
     2  package grpc
     3  
     4  import (
     5  	"context"
     6  	"crypto/tls"
     7  	"fmt"
     8  	"net"
     9  	"reflect"
    10  	"runtime/debug"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/annwntech/go-micro/v2/broker"
    18  	"github.com/annwntech/go-micro/v2/errors"
    19  	"github.com/annwntech/go-micro/v2/logger"
    20  	meta "github.com/annwntech/go-micro/v2/metadata"
    21  	"github.com/annwntech/go-micro/v2/registry"
    22  	"github.com/annwntech/go-micro/v2/server"
    23  	"github.com/annwntech/go-micro/v2/util/addr"
    24  	"github.com/annwntech/go-micro/v2/util/backoff"
    25  	mgrpc "github.com/annwntech/go-micro/v2/util/grpc"
    26  	mnet "github.com/annwntech/go-micro/v2/util/net"
    27  	"github.com/golang/protobuf/proto"
    28  	"golang.org/x/net/netutil"
    29  
    30  	"google.golang.org/grpc"
    31  	"google.golang.org/grpc/codes"
    32  	"google.golang.org/grpc/credentials"
    33  	"google.golang.org/grpc/encoding"
    34  	"google.golang.org/grpc/metadata"
    35  	"google.golang.org/grpc/peer"
    36  	"google.golang.org/grpc/status"
    37  )
    38  
    39  var (
    40  	// DefaultMaxMsgSize define maximum message size that server can send
    41  	// or receive.  Default value is 4MB.
    42  	DefaultMaxMsgSize = 1024 * 1024 * 4
    43  )
    44  
    45  const (
    46  	defaultContentType = "application/grpc"
    47  )
    48  
    49  type grpcServer struct {
    50  	rpc  *rServer
    51  	srv  *grpc.Server
    52  	exit chan chan error
    53  	wg   *sync.WaitGroup
    54  
    55  	sync.RWMutex
    56  	opts        server.Options
    57  	handlers    map[string]server.Handler
    58  	subscribers map[*subscriber][]broker.Subscriber
    59  	// marks the serve as started
    60  	started bool
    61  	// used for first registration
    62  	registered bool
    63  
    64  	// registry service instance
    65  	rsvc *registry.Service
    66  }
    67  
    68  func init() {
    69  	encoding.RegisterCodec(wrapCodec{jsonCodec{}})
    70  	encoding.RegisterCodec(wrapCodec{protoCodec{}})
    71  	encoding.RegisterCodec(wrapCodec{bytesCodec{}})
    72  }
    73  
    74  func newGRPCServer(opts ...server.Option) server.Server {
    75  	options := newOptions(opts...)
    76  
    77  	// create a grpc server
    78  	srv := &grpcServer{
    79  		opts: options,
    80  		rpc: &rServer{
    81  			serviceMap: make(map[string]*service),
    82  		},
    83  		handlers:    make(map[string]server.Handler),
    84  		subscribers: make(map[*subscriber][]broker.Subscriber),
    85  		exit:        make(chan chan error),
    86  		wg:          wait(options.Context),
    87  	}
    88  
    89  	// configure the grpc server
    90  	srv.configure()
    91  
    92  	return srv
    93  }
    94  
    95  type grpcRouter struct {
    96  	h func(context.Context, server.Request, interface{}) error
    97  	m func(context.Context, server.Message) error
    98  }
    99  
   100  func (r grpcRouter) ProcessMessage(ctx context.Context, msg server.Message) error {
   101  	return r.m(ctx, msg)
   102  }
   103  
   104  func (r grpcRouter) ServeRequest(ctx context.Context, req server.Request, rsp server.Response) error {
   105  	return r.h(ctx, req, rsp)
   106  }
   107  
   108  func (g *grpcServer) configure(opts ...server.Option) {
   109  	g.Lock()
   110  	defer g.Unlock()
   111  
   112  	// Don't reprocess where there's no config
   113  	if len(opts) == 0 && g.srv != nil {
   114  		return
   115  	}
   116  
   117  	for _, o := range opts {
   118  		o(&g.opts)
   119  	}
   120  
   121  	maxMsgSize := g.getMaxMsgSize()
   122  
   123  	gopts := []grpc.ServerOption{
   124  		grpc.MaxRecvMsgSize(maxMsgSize),
   125  		grpc.MaxSendMsgSize(maxMsgSize),
   126  		grpc.UnknownServiceHandler(g.handler),
   127  	}
   128  
   129  	if creds := g.getCredentials(); creds != nil {
   130  		gopts = append(gopts, grpc.Creds(creds))
   131  	}
   132  
   133  	if opts := g.getGrpcOptions(); opts != nil {
   134  		gopts = append(gopts, opts...)
   135  	}
   136  
   137  	g.rsvc = nil
   138  	g.srv = grpc.NewServer(gopts...)
   139  }
   140  
   141  func (g *grpcServer) getMaxMsgSize() int {
   142  	if g.opts.Context == nil {
   143  		return DefaultMaxMsgSize
   144  	}
   145  	s, ok := g.opts.Context.Value(maxMsgSizeKey{}).(int)
   146  	if !ok {
   147  		return DefaultMaxMsgSize
   148  	}
   149  	return s
   150  }
   151  
   152  func (g *grpcServer) getCredentials() credentials.TransportCredentials {
   153  	if g.opts.Context != nil {
   154  		if v, ok := g.opts.Context.Value(tlsAuth{}).(*tls.Config); ok && v != nil {
   155  			return credentials.NewTLS(v)
   156  		}
   157  	}
   158  	return nil
   159  }
   160  
   161  func (g *grpcServer) getGrpcOptions() []grpc.ServerOption {
   162  	if g.opts.Context == nil {
   163  		return nil
   164  	}
   165  
   166  	opts, ok := g.opts.Context.Value(grpcOptions{}).([]grpc.ServerOption)
   167  	if !ok || opts == nil {
   168  		return nil
   169  	}
   170  
   171  	return opts
   172  }
   173  
   174  func (g *grpcServer) getListener() net.Listener {
   175  	if g.opts.Context == nil {
   176  		return nil
   177  	}
   178  
   179  	if l, ok := g.opts.Context.Value(netListener{}).(net.Listener); ok && l != nil {
   180  		return l
   181  	}
   182  
   183  	return nil
   184  }
   185  
   186  func (g *grpcServer) handler(srv interface{}, stream grpc.ServerStream) error {
   187  	if g.wg != nil {
   188  		g.wg.Add(1)
   189  		defer g.wg.Done()
   190  	}
   191  
   192  	fullMethod, ok := grpc.MethodFromServerStream(stream)
   193  	if !ok {
   194  		return status.Errorf(codes.Internal, "method does not exist in context")
   195  	}
   196  
   197  	serviceName, methodName, err := mgrpc.ServiceMethod(fullMethod)
   198  	if err != nil {
   199  		return status.New(codes.InvalidArgument, err.Error()).Err()
   200  	}
   201  
   202  	// get grpc metadata
   203  	gmd, ok := metadata.FromIncomingContext(stream.Context())
   204  	if !ok {
   205  		gmd = metadata.MD{}
   206  	}
   207  
   208  	// copy the metadata to go-micro.metadata
   209  	md := meta.Metadata{}
   210  	for k, v := range gmd {
   211  		md[k] = strings.Join(v, ", ")
   212  	}
   213  
   214  	// timeout for server deadline
   215  	to := md["timeout"]
   216  
   217  	// get content type
   218  	ct := defaultContentType
   219  
   220  	if ctype, ok := md["x-content-type"]; ok {
   221  		ct = ctype
   222  	}
   223  	if ctype, ok := md["content-type"]; ok {
   224  		ct = ctype
   225  	}
   226  
   227  	delete(md, "x-content-type")
   228  	delete(md, "timeout")
   229  
   230  	// create new context
   231  	ctx := meta.NewContext(stream.Context(), md)
   232  
   233  	// get peer from context
   234  	if p, ok := peer.FromContext(stream.Context()); ok {
   235  		md["Remote"] = p.Addr.String()
   236  		ctx = peer.NewContext(ctx, p)
   237  	}
   238  
   239  	// set the timeout if we have it
   240  	if len(to) > 0 {
   241  		if n, err := strconv.ParseUint(to, 10, 64); err == nil {
   242  			var cancel context.CancelFunc
   243  			ctx, cancel = context.WithTimeout(ctx, time.Duration(n))
   244  			defer cancel()
   245  		}
   246  	}
   247  
   248  	// process via router
   249  	if g.opts.Router != nil {
   250  		cc, err := g.newGRPCCodec(ct)
   251  		if err != nil {
   252  			return errors.InternalServerError("go.micro.server", err.Error())
   253  		}
   254  		codec := &grpcCodec{
   255  			method:   fmt.Sprintf("%s.%s", serviceName, methodName),
   256  			endpoint: fmt.Sprintf("%s.%s", serviceName, methodName),
   257  			target:   g.opts.Name,
   258  			s:        stream,
   259  			c:        cc,
   260  		}
   261  
   262  		// create a client.Request
   263  		request := &rpcRequest{
   264  			service:     mgrpc.ServiceFromMethod(fullMethod),
   265  			contentType: ct,
   266  			method:      fmt.Sprintf("%s.%s", serviceName, methodName),
   267  			codec:       codec,
   268  			stream:      true,
   269  		}
   270  
   271  		response := &rpcResponse{
   272  			header: make(map[string]string),
   273  			codec:  codec,
   274  		}
   275  
   276  		// create a wrapped function
   277  		handler := func(ctx context.Context, req server.Request, rsp interface{}) error {
   278  			return g.opts.Router.ServeRequest(ctx, req, rsp.(server.Response))
   279  		}
   280  
   281  		// execute the wrapper for it
   282  		for i := len(g.opts.HdlrWrappers); i > 0; i-- {
   283  			handler = g.opts.HdlrWrappers[i-1](handler)
   284  		}
   285  
   286  		r := grpcRouter{h: handler}
   287  
   288  		// serve the actual request using the request router
   289  		if err := r.ServeRequest(ctx, request, response); err != nil {
   290  			if _, ok := status.FromError(err); ok {
   291  				return err
   292  			}
   293  			return status.Errorf(codes.Internal, err.Error())
   294  		}
   295  
   296  		return nil
   297  	}
   298  
   299  	// process the standard request flow
   300  	g.rpc.mu.Lock()
   301  	service := g.rpc.serviceMap[serviceName]
   302  	g.rpc.mu.Unlock()
   303  
   304  	if service == nil {
   305  		return status.New(codes.Unimplemented, fmt.Sprintf("unknown service %s", serviceName)).Err()
   306  	}
   307  
   308  	mtype := service.method[methodName]
   309  	if mtype == nil {
   310  		return status.New(codes.Unimplemented, fmt.Sprintf("unknown service %s.%s", serviceName, methodName)).Err()
   311  	}
   312  
   313  	// process unary
   314  	if !mtype.stream {
   315  		return g.processRequest(stream, service, mtype, ct, ctx)
   316  	}
   317  
   318  	// process stream
   319  	return g.processStream(stream, service, mtype, ct, ctx)
   320  }
   321  
   322  func (g *grpcServer) processRequest(stream grpc.ServerStream, service *service, mtype *methodType, ct string, ctx context.Context) error {
   323  	for {
   324  		var argv, replyv reflect.Value
   325  
   326  		// Decode the argument value.
   327  		argIsValue := false // if true, need to indirect before calling.
   328  		if mtype.ArgType.Kind() == reflect.Ptr {
   329  			argv = reflect.New(mtype.ArgType.Elem())
   330  		} else {
   331  			argv = reflect.New(mtype.ArgType)
   332  			argIsValue = true
   333  		}
   334  
   335  		// Unmarshal request
   336  		if err := stream.RecvMsg(argv.Interface()); err != nil {
   337  			return err
   338  		}
   339  
   340  		if argIsValue {
   341  			argv = argv.Elem()
   342  		}
   343  
   344  		// reply value
   345  		replyv = reflect.New(mtype.ReplyType.Elem())
   346  
   347  		function := mtype.method.Func
   348  		var returnValues []reflect.Value
   349  
   350  		cc, err := g.newGRPCCodec(ct)
   351  		if err != nil {
   352  			return errors.InternalServerError("go.micro.server", err.Error())
   353  		}
   354  		b, err := cc.Marshal(argv.Interface())
   355  		if err != nil {
   356  			return err
   357  		}
   358  
   359  		// create a client.Request
   360  		r := &rpcRequest{
   361  			service:     g.opts.Name,
   362  			contentType: ct,
   363  			method:      fmt.Sprintf("%s.%s", service.name, mtype.method.Name),
   364  			body:        b,
   365  			payload:     argv.Interface(),
   366  		}
   367  
   368  		// define the handler func
   369  		fn := func(ctx context.Context, req server.Request, rsp interface{}) (err error) {
   370  			defer func() {
   371  				if r := recover(); r != nil {
   372  					if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   373  						logger.Error("panic recovered: ", r)
   374  						logger.Error(string(debug.Stack()))
   375  					}
   376  					err = errors.InternalServerError("go.micro.server", "panic recovered: %v", r)
   377  				}
   378  			}()
   379  			returnValues = function.Call([]reflect.Value{service.rcvr, mtype.prepareContext(ctx), reflect.ValueOf(argv.Interface()), reflect.ValueOf(rsp)})
   380  
   381  			// The return value for the method is an error.
   382  			if rerr := returnValues[0].Interface(); rerr != nil {
   383  				err = rerr.(error)
   384  			}
   385  
   386  			return err
   387  		}
   388  
   389  		// wrap the handler func
   390  		for i := len(g.opts.HdlrWrappers); i > 0; i-- {
   391  			fn = g.opts.HdlrWrappers[i-1](fn)
   392  		}
   393  		statusCode := codes.OK
   394  		statusDesc := ""
   395  		// execute the handler
   396  		if appErr := fn(ctx, r, replyv.Interface()); appErr != nil {
   397  			var errStatus *status.Status
   398  			switch verr := appErr.(type) {
   399  			case *errors.Error:
   400  				// micro.Error now proto based and we can attach it to grpc status
   401  				statusCode = microError(verr)
   402  				statusDesc = verr.Error()
   403  				errStatus, err = status.New(statusCode, statusDesc).WithDetails(verr)
   404  				if err != nil {
   405  					return err
   406  				}
   407  			case proto.Message:
   408  				// user defined error that proto based we can attach it to grpc status
   409  				statusCode = convertCode(appErr)
   410  				statusDesc = appErr.Error()
   411  				errStatus, err = status.New(statusCode, statusDesc).WithDetails(verr)
   412  				if err != nil {
   413  					return err
   414  				}
   415  			default:
   416  				// default case user pass own error type that not proto based
   417  				statusCode = convertCode(verr)
   418  				statusDesc = verr.Error()
   419  				errStatus = status.New(statusCode, statusDesc)
   420  			}
   421  
   422  			return errStatus.Err()
   423  		}
   424  
   425  		if err := stream.SendMsg(replyv.Interface()); err != nil {
   426  			return err
   427  		}
   428  		return status.New(statusCode, statusDesc).Err()
   429  	}
   430  }
   431  
   432  func (g *grpcServer) processStream(stream grpc.ServerStream, service *service, mtype *methodType, ct string, ctx context.Context) error {
   433  	opts := g.opts
   434  
   435  	r := &rpcRequest{
   436  		service:     opts.Name,
   437  		contentType: ct,
   438  		method:      fmt.Sprintf("%s.%s", service.name, mtype.method.Name),
   439  		stream:      true,
   440  	}
   441  
   442  	ss := &rpcStream{
   443  		request: r,
   444  		s:       stream,
   445  	}
   446  
   447  	function := mtype.method.Func
   448  	var returnValues []reflect.Value
   449  
   450  	// Invoke the method, providing a new value for the reply.
   451  	fn := func(ctx context.Context, req server.Request, stream interface{}) error {
   452  		returnValues = function.Call([]reflect.Value{service.rcvr, mtype.prepareContext(ctx), reflect.ValueOf(stream)})
   453  		if err := returnValues[0].Interface(); err != nil {
   454  			return err.(error)
   455  		}
   456  
   457  		return nil
   458  	}
   459  
   460  	for i := len(opts.HdlrWrappers); i > 0; i-- {
   461  		fn = opts.HdlrWrappers[i-1](fn)
   462  	}
   463  
   464  	statusCode := codes.OK
   465  	statusDesc := ""
   466  
   467  	if appErr := fn(ctx, r, ss); appErr != nil {
   468  		var err error
   469  		var errStatus *status.Status
   470  		switch verr := appErr.(type) {
   471  		case *errors.Error:
   472  			// micro.Error now proto based and we can attach it to grpc status
   473  			statusCode = microError(verr)
   474  			statusDesc = verr.Error()
   475  			errStatus, err = status.New(statusCode, statusDesc).WithDetails(verr)
   476  			if err != nil {
   477  				return err
   478  			}
   479  		case proto.Message:
   480  			// user defined error that proto based we can attach it to grpc status
   481  			statusCode = convertCode(appErr)
   482  			statusDesc = appErr.Error()
   483  			errStatus, err = status.New(statusCode, statusDesc).WithDetails(verr)
   484  			if err != nil {
   485  				return err
   486  			}
   487  		default:
   488  			// default case user pass own error type that not proto based
   489  			statusCode = convertCode(verr)
   490  			statusDesc = verr.Error()
   491  			errStatus = status.New(statusCode, statusDesc)
   492  		}
   493  		return errStatus.Err()
   494  	}
   495  
   496  	return status.New(statusCode, statusDesc).Err()
   497  }
   498  
   499  func (g *grpcServer) newGRPCCodec(contentType string) (encoding.Codec, error) {
   500  	codecs := make(map[string]encoding.Codec)
   501  	if g.opts.Context != nil {
   502  		if v, ok := g.opts.Context.Value(codecsKey{}).(map[string]encoding.Codec); ok && v != nil {
   503  			codecs = v
   504  		}
   505  	}
   506  	if c, ok := codecs[contentType]; ok {
   507  		return c, nil
   508  	}
   509  	if c, ok := defaultGRPCCodecs[contentType]; ok {
   510  		return c, nil
   511  	}
   512  	return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
   513  }
   514  
   515  func (g *grpcServer) Options() server.Options {
   516  	g.RLock()
   517  	opts := g.opts
   518  	g.RUnlock()
   519  
   520  	return opts
   521  }
   522  
   523  func (g *grpcServer) Init(opts ...server.Option) error {
   524  	g.configure(opts...)
   525  	return nil
   526  }
   527  
   528  func (g *grpcServer) NewHandler(h interface{}, opts ...server.HandlerOption) server.Handler {
   529  	return newRpcHandler(h, opts...)
   530  }
   531  
   532  func (g *grpcServer) Handle(h server.Handler) error {
   533  	if err := g.rpc.register(h.Handler()); err != nil {
   534  		return err
   535  	}
   536  
   537  	g.handlers[h.Name()] = h
   538  	return nil
   539  }
   540  
   541  func (g *grpcServer) NewSubscriber(topic string, sb interface{}, opts ...server.SubscriberOption) server.Subscriber {
   542  	return newSubscriber(topic, sb, opts...)
   543  }
   544  
   545  func (g *grpcServer) Subscribe(sb server.Subscriber) error {
   546  	sub, ok := sb.(*subscriber)
   547  	if !ok {
   548  		return fmt.Errorf("invalid subscriber: expected *subscriber")
   549  	}
   550  	if len(sub.handlers) == 0 {
   551  		return fmt.Errorf("invalid subscriber: no handler functions")
   552  	}
   553  
   554  	if err := validateSubscriber(sb); err != nil {
   555  		return err
   556  	}
   557  
   558  	g.Lock()
   559  	if _, ok = g.subscribers[sub]; ok {
   560  		g.Unlock()
   561  		return fmt.Errorf("subscriber %v already exists", sub)
   562  	}
   563  
   564  	g.subscribers[sub] = nil
   565  	g.Unlock()
   566  	return nil
   567  }
   568  
   569  func (g *grpcServer) Register() error {
   570  	g.RLock()
   571  	rsvc := g.rsvc
   572  	config := g.opts
   573  	g.RUnlock()
   574  
   575  	regFunc := func(service *registry.Service) error {
   576  		var regErr error
   577  
   578  		for i := 0; i < 3; i++ {
   579  			// set the ttl
   580  			rOpts := []registry.RegisterOption{registry.RegisterTTL(config.RegisterTTL)}
   581  			// attempt to register
   582  			if err := config.Registry.Register(service, rOpts...); err != nil {
   583  				// set the error
   584  				regErr = err
   585  				// backoff then retry
   586  				time.Sleep(backoff.Do(i + 1))
   587  				continue
   588  			}
   589  			// success so nil error
   590  			regErr = nil
   591  			break
   592  		}
   593  
   594  		return regErr
   595  	}
   596  
   597  	// if service already filled, reuse it and return early
   598  	if rsvc != nil {
   599  		if err := regFunc(rsvc); err != nil {
   600  			return err
   601  		}
   602  		return nil
   603  	}
   604  
   605  	var err error
   606  	var advt, host, port string
   607  	var cacheService bool
   608  
   609  	// check the advertise address first
   610  	// if it exists then use it, otherwise
   611  	// use the address
   612  	if len(config.Advertise) > 0 {
   613  		advt = config.Advertise
   614  	} else {
   615  		advt = config.Address
   616  	}
   617  
   618  	if cnt := strings.Count(advt, ":"); cnt >= 1 {
   619  		// ipv6 address in format [host]:port or ipv4 host:port
   620  		host, port, err = net.SplitHostPort(advt)
   621  		if err != nil {
   622  			return err
   623  		}
   624  	} else {
   625  		host = advt
   626  	}
   627  
   628  	if ip := net.ParseIP(host); ip != nil {
   629  		cacheService = true
   630  	}
   631  
   632  	addr, err := addr.Extract(host)
   633  	if err != nil {
   634  		return err
   635  	}
   636  
   637  	// make copy of metadata
   638  	md := meta.Copy(config.Metadata)
   639  
   640  	// register service
   641  	node := &registry.Node{
   642  		Id:       config.Name + "-" + config.Id,
   643  		Address:  mnet.HostPort(addr, port),
   644  		Metadata: md,
   645  	}
   646  
   647  	node.Metadata["broker"] = config.Broker.String()
   648  	node.Metadata["registry"] = config.Registry.String()
   649  	node.Metadata["server"] = g.String()
   650  	node.Metadata["transport"] = g.String()
   651  	node.Metadata["protocol"] = "grpc"
   652  
   653  	g.RLock()
   654  	// Maps are ordered randomly, sort the keys for consistency
   655  	var handlerList []string
   656  	for n, e := range g.handlers {
   657  		// Only advertise non internal handlers
   658  		if !e.Options().Internal {
   659  			handlerList = append(handlerList, n)
   660  		}
   661  	}
   662  	sort.Strings(handlerList)
   663  
   664  	var subscriberList []*subscriber
   665  	for e := range g.subscribers {
   666  		// Only advertise non internal subscribers
   667  		if !e.Options().Internal {
   668  			subscriberList = append(subscriberList, e)
   669  		}
   670  	}
   671  	sort.Slice(subscriberList, func(i, j int) bool {
   672  		return subscriberList[i].topic > subscriberList[j].topic
   673  	})
   674  
   675  	endpoints := make([]*registry.Endpoint, 0, len(handlerList)+len(subscriberList))
   676  	for _, n := range handlerList {
   677  		endpoints = append(endpoints, g.handlers[n].Endpoints()...)
   678  	}
   679  	for _, e := range subscriberList {
   680  		endpoints = append(endpoints, e.Endpoints()...)
   681  	}
   682  	g.RUnlock()
   683  
   684  	service := &registry.Service{
   685  		Name:      config.Name,
   686  		Version:   config.Version,
   687  		Nodes:     []*registry.Node{node},
   688  		Endpoints: endpoints,
   689  	}
   690  
   691  	g.RLock()
   692  	registered := g.registered
   693  	g.RUnlock()
   694  
   695  	if !registered {
   696  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   697  			logger.Infof("Registry [%s] Registering node: %s", config.Registry.String(), node.Id)
   698  		}
   699  	}
   700  
   701  	// register the service
   702  	if err := regFunc(service); err != nil {
   703  		return err
   704  	}
   705  
   706  	// already registered? don't need to register subscribers
   707  	if registered {
   708  		return nil
   709  	}
   710  
   711  	g.Lock()
   712  	defer g.Unlock()
   713  
   714  	for sb := range g.subscribers {
   715  		handler := g.createSubHandler(sb, g.opts)
   716  		var opts []broker.SubscribeOption
   717  		if queue := sb.Options().Queue; len(queue) > 0 {
   718  			opts = append(opts, broker.Queue(queue))
   719  		}
   720  
   721  		if cx := sb.Options().Context; cx != nil {
   722  			opts = append(opts, broker.SubscribeContext(cx))
   723  		}
   724  
   725  		if !sb.Options().AutoAck {
   726  			opts = append(opts, broker.DisableAutoAck())
   727  		}
   728  
   729  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   730  			logger.Infof("Subscribing to topic: %s", sb.Topic())
   731  		}
   732  		sub, err := config.Broker.Subscribe(sb.Topic(), handler, opts...)
   733  		if err != nil {
   734  			return err
   735  		}
   736  		g.subscribers[sb] = []broker.Subscriber{sub}
   737  	}
   738  
   739  	g.registered = true
   740  	if cacheService {
   741  		g.rsvc = service
   742  	}
   743  
   744  	return nil
   745  }
   746  
   747  func (g *grpcServer) Deregister() error {
   748  	var err error
   749  	var advt, host, port string
   750  
   751  	g.RLock()
   752  	config := g.opts
   753  	g.RUnlock()
   754  
   755  	// check the advertise address first
   756  	// if it exists then use it, otherwise
   757  	// use the address
   758  	if len(config.Advertise) > 0 {
   759  		advt = config.Advertise
   760  	} else {
   761  		advt = config.Address
   762  	}
   763  
   764  	if cnt := strings.Count(advt, ":"); cnt >= 1 {
   765  		// ipv6 address in format [host]:port or ipv4 host:port
   766  		host, port, err = net.SplitHostPort(advt)
   767  		if err != nil {
   768  			return err
   769  		}
   770  	} else {
   771  		host = advt
   772  	}
   773  
   774  	addr, err := addr.Extract(host)
   775  	if err != nil {
   776  		return err
   777  	}
   778  
   779  	node := &registry.Node{
   780  		Id:      config.Name + "-" + config.Id,
   781  		Address: mnet.HostPort(addr, port),
   782  	}
   783  
   784  	service := &registry.Service{
   785  		Name:    config.Name,
   786  		Version: config.Version,
   787  		Nodes:   []*registry.Node{node},
   788  	}
   789  
   790  	if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   791  		logger.Infof("Deregistering node: %s", node.Id)
   792  	}
   793  	if err := config.Registry.Deregister(service); err != nil {
   794  		return err
   795  	}
   796  
   797  	g.Lock()
   798  	g.rsvc = nil
   799  
   800  	if !g.registered {
   801  		g.Unlock()
   802  		return nil
   803  	}
   804  
   805  	g.registered = false
   806  
   807  	wg := sync.WaitGroup{}
   808  	for sb, subs := range g.subscribers {
   809  		for _, sub := range subs {
   810  			wg.Add(1)
   811  			go func(s broker.Subscriber) {
   812  				defer wg.Done()
   813  				if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   814  					logger.Infof("Unsubscribing from topic: %s", s.Topic())
   815  				}
   816  				s.Unsubscribe()
   817  			}(sub)
   818  		}
   819  		g.subscribers[sb] = nil
   820  	}
   821  	wg.Wait()
   822  
   823  	g.Unlock()
   824  	return nil
   825  }
   826  
   827  func (g *grpcServer) Start() error {
   828  	g.RLock()
   829  	if g.started {
   830  		g.RUnlock()
   831  		return nil
   832  	}
   833  	g.RUnlock()
   834  
   835  	config := g.Options()
   836  
   837  	// micro: config.Transport.Listen(config.Address)
   838  	var ts net.Listener
   839  
   840  	if l := g.getListener(); l != nil {
   841  		ts = l
   842  	} else {
   843  		var err error
   844  
   845  		// check the tls config for secure connect
   846  		if tc := config.TLSConfig; tc != nil {
   847  			ts, err = tls.Listen("tcp", config.Address, tc)
   848  			// otherwise just plain tcp listener
   849  		} else {
   850  			ts, err = net.Listen("tcp", config.Address)
   851  		}
   852  		if err != nil {
   853  			return err
   854  		}
   855  	}
   856  
   857  	if g.opts.Context != nil {
   858  		if c, ok := g.opts.Context.Value(maxConnKey{}).(int); ok && c > 0 {
   859  			ts = netutil.LimitListener(ts, c)
   860  		}
   861  	}
   862  
   863  	if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   864  		logger.Infof("Server [grpc] Listening on %s", ts.Addr().String())
   865  	}
   866  	g.Lock()
   867  	g.opts.Address = ts.Addr().String()
   868  	g.Unlock()
   869  
   870  	// only connect if we're subscribed
   871  	if len(g.subscribers) > 0 {
   872  		// connect to the broker
   873  		if err := config.Broker.Connect(); err != nil {
   874  			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   875  				logger.Errorf("Broker [%s] connect error: %v", config.Broker.String(), err)
   876  			}
   877  			return err
   878  		}
   879  
   880  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   881  			logger.Infof("Broker [%s] Connected to %s", config.Broker.String(), config.Broker.Address())
   882  		}
   883  	}
   884  
   885  	// announce self to the world
   886  	if err := g.Register(); err != nil {
   887  		if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   888  			logger.Errorf("Server register error: %v", err)
   889  		}
   890  	}
   891  
   892  	// micro: go ts.Accept(s.accept)
   893  	go func() {
   894  		if err := g.srv.Serve(ts); err != nil {
   895  			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   896  				logger.Errorf("gRPC Server start error: %v", err)
   897  			}
   898  		}
   899  	}()
   900  
   901  	go func() {
   902  		t := new(time.Ticker)
   903  
   904  		// only process if it exists
   905  		if g.opts.RegisterInterval > time.Duration(0) {
   906  			// new ticker
   907  			t = time.NewTicker(g.opts.RegisterInterval)
   908  		}
   909  
   910  		// return error chan
   911  		var ch chan error
   912  
   913  	Loop:
   914  		for {
   915  			select {
   916  			// register self on interval
   917  			case <-t.C:
   918  				if err := g.Register(); err != nil {
   919  					if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   920  						logger.Error("Server register error: ", err)
   921  					}
   922  				}
   923  			// wait for exit
   924  			case ch = <-g.exit:
   925  				break Loop
   926  			}
   927  		}
   928  
   929  		// deregister self
   930  		if err := g.Deregister(); err != nil {
   931  			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   932  				logger.Error("Server deregister error: ", err)
   933  			}
   934  		}
   935  
   936  		// wait for waitgroup
   937  		if g.wg != nil {
   938  			g.wg.Wait()
   939  		}
   940  
   941  		// stop the grpc server
   942  		exit := make(chan bool)
   943  
   944  		go func() {
   945  			g.srv.GracefulStop()
   946  			close(exit)
   947  		}()
   948  
   949  		select {
   950  		case <-exit:
   951  		case <-time.After(time.Second):
   952  			g.srv.Stop()
   953  		}
   954  
   955  		// close transport
   956  		ch <- nil
   957  
   958  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   959  			logger.Infof("Broker [%s] Disconnected from %s", config.Broker.String(), config.Broker.Address())
   960  		}
   961  		// disconnect broker
   962  		if err := config.Broker.Disconnect(); err != nil {
   963  			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   964  				logger.Errorf("Broker [%s] disconnect error: %v", config.Broker.String(), err)
   965  			}
   966  		}
   967  	}()
   968  
   969  	// mark the server as started
   970  	g.Lock()
   971  	g.started = true
   972  	g.Unlock()
   973  
   974  	return nil
   975  }
   976  
   977  func (g *grpcServer) Stop() error {
   978  	g.RLock()
   979  	if !g.started {
   980  		g.RUnlock()
   981  		return nil
   982  	}
   983  	g.RUnlock()
   984  
   985  	ch := make(chan error)
   986  	g.exit <- ch
   987  
   988  	var err error
   989  	select {
   990  	case err = <-ch:
   991  		g.Lock()
   992  		g.rsvc = nil
   993  		g.started = false
   994  		g.Unlock()
   995  	}
   996  
   997  	return err
   998  }
   999  
  1000  func (g *grpcServer) String() string {
  1001  	return "grpc"
  1002  }
  1003  
  1004  func NewServer(opts ...server.Option) server.Server {
  1005  	return newGRPCServer(opts...)
  1006  }