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