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

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"net"
     8  	"runtime/debug"
     9  	"sort"
    10  	"strconv"
    11  	"strings"
    12  	"sync"
    13  	"time"
    14  
    15  	"github.com/annwntech/go-micro/v2/broker"
    16  	"github.com/annwntech/go-micro/v2/codec"
    17  	raw "github.com/annwntech/go-micro/v2/codec/bytes"
    18  	"github.com/annwntech/go-micro/v2/logger"
    19  	"github.com/annwntech/go-micro/v2/metadata"
    20  	"github.com/annwntech/go-micro/v2/registry"
    21  	"github.com/annwntech/go-micro/v2/transport"
    22  	"github.com/annwntech/go-micro/v2/util/addr"
    23  	"github.com/annwntech/go-micro/v2/util/backoff"
    24  	mnet "github.com/annwntech/go-micro/v2/util/net"
    25  	"github.com/annwntech/go-micro/v2/util/socket"
    26  )
    27  
    28  type rpcServer struct {
    29  	router *router
    30  	exit   chan chan error
    31  
    32  	sync.RWMutex
    33  	opts        Options
    34  	handlers    map[string]Handler
    35  	subscribers map[Subscriber][]broker.Subscriber
    36  	// marks the serve as started
    37  	started bool
    38  	// used for first registration
    39  	registered bool
    40  	// subscribe to service name
    41  	subscriber broker.Subscriber
    42  	// graceful exit
    43  	wg *sync.WaitGroup
    44  
    45  	rsvc *registry.Service
    46  }
    47  
    48  func newRpcServer(opts ...Option) Server {
    49  	options := newOptions(opts...)
    50  	router := newRpcRouter()
    51  	router.hdlrWrappers = options.HdlrWrappers
    52  	router.subWrappers = options.SubWrappers
    53  
    54  	return &rpcServer{
    55  		opts:        options,
    56  		router:      router,
    57  		handlers:    make(map[string]Handler),
    58  		subscribers: make(map[Subscriber][]broker.Subscriber),
    59  		exit:        make(chan chan error),
    60  		wg:          wait(options.Context),
    61  	}
    62  }
    63  
    64  // HandleEvent handles inbound messages to the service directly
    65  // TODO: handle requests from an event. We won't send a response.
    66  func (s *rpcServer) HandleEvent(e broker.Event) error {
    67  	// formatting horrible cruft
    68  	msg := e.Message()
    69  
    70  	if msg.Header == nil {
    71  		// create empty map in case of headers empty to avoid panic later
    72  		msg.Header = make(map[string]string)
    73  	}
    74  
    75  	// get codec
    76  	ct := msg.Header["Content-Type"]
    77  
    78  	// default content type
    79  	if len(ct) == 0 {
    80  		msg.Header["Content-Type"] = DefaultContentType
    81  		ct = DefaultContentType
    82  	}
    83  
    84  	// get codec
    85  	cf, err := s.newCodec(ct)
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	// copy headers
    91  	hdr := make(map[string]string, len(msg.Header))
    92  	for k, v := range msg.Header {
    93  		hdr[k] = v
    94  	}
    95  
    96  	// create context
    97  	ctx := metadata.NewContext(context.Background(), hdr)
    98  
    99  	// TODO: inspect message header
   100  	// Micro-Service means a request
   101  	// Micro-Topic means a message
   102  
   103  	rpcMsg := &rpcMessage{
   104  		topic:       msg.Header["Micro-Topic"],
   105  		contentType: ct,
   106  		payload:     &raw.Frame{Data: msg.Body},
   107  		codec:       cf,
   108  		header:      msg.Header,
   109  		body:        msg.Body,
   110  	}
   111  
   112  	// existing router
   113  	r := Router(s.router)
   114  
   115  	// if the router is present then execute it
   116  	if s.opts.Router != nil {
   117  		// create a wrapped function
   118  		handler := s.opts.Router.ProcessMessage
   119  
   120  		// execute the wrapper for it
   121  		for i := len(s.opts.SubWrappers); i > 0; i-- {
   122  			handler = s.opts.SubWrappers[i-1](handler)
   123  		}
   124  
   125  		// set the router
   126  		r = rpcRouter{m: handler}
   127  	}
   128  
   129  	return r.ProcessMessage(ctx, rpcMsg)
   130  }
   131  
   132  // ServeConn serves a single connection
   133  func (s *rpcServer) ServeConn(sock transport.Socket) {
   134  	// global error tracking
   135  	var gerr error
   136  	// streams are multiplexed on Micro-Stream or Micro-Id header
   137  	pool := socket.NewPool()
   138  
   139  	// get global waitgroup
   140  	s.Lock()
   141  	gg := s.wg
   142  	s.Unlock()
   143  
   144  	// waitgroup to wait for processing to finish
   145  	wg := &waitGroup{
   146  		gg: gg,
   147  	}
   148  
   149  	defer func() {
   150  		// only wait if there's no error
   151  		if gerr == nil {
   152  			// wait till done
   153  			wg.Wait()
   154  		}
   155  
   156  		// close all the sockets for this connection
   157  		pool.Close()
   158  
   159  		// close underlying socket
   160  		sock.Close()
   161  
   162  		// recover any panics
   163  		if r := recover(); r != nil {
   164  			if logger.V(logger.ErrorLevel, log) {
   165  				log.Error("panic recovered: ", r)
   166  				log.Error(string(debug.Stack()))
   167  			}
   168  		}
   169  	}()
   170  
   171  	for {
   172  		var msg transport.Message
   173  		// process inbound messages one at a time
   174  		if err := sock.Recv(&msg); err != nil {
   175  			// set a global error and return
   176  			// we're saying we essentially can't
   177  			// use the socket anymore
   178  			gerr = err
   179  			return
   180  		}
   181  
   182  		// check the message header for
   183  		// Micro-Service is a request
   184  		// Micro-Topic is a message
   185  		if t := msg.Header["Micro-Topic"]; len(t) > 0 {
   186  			// process the event
   187  			ev := newEvent(msg)
   188  			// TODO: handle the error event
   189  			if err := s.HandleEvent(ev); err != nil {
   190  				msg.Header["Micro-Error"] = err.Error()
   191  			}
   192  			// write back some 200
   193  			if err := sock.Send(&transport.Message{
   194  				Header: msg.Header,
   195  			}); err != nil {
   196  				gerr = err
   197  				break
   198  			}
   199  			// we're done
   200  			continue
   201  		}
   202  
   203  		// business as usual
   204  
   205  		// use Micro-Stream as the stream identifier
   206  		// in the event its blank we'll always process
   207  		// on the same socket
   208  		id := msg.Header["Micro-Stream"]
   209  
   210  		// if there's no stream id then its a standard request
   211  		// use the Micro-Id
   212  		if len(id) == 0 {
   213  			id = msg.Header["Micro-Id"]
   214  		}
   215  
   216  		// check stream id
   217  		var stream bool
   218  
   219  		if v := getHeader("Micro-Stream", msg.Header); len(v) > 0 {
   220  			stream = true
   221  		}
   222  
   223  		// check if we have an existing socket
   224  		psock, ok := pool.Get(id)
   225  
   226  		// if we don't have a socket and its a stream
   227  		if !ok && stream {
   228  			// check if its a last stream EOS error
   229  			err := msg.Header["Micro-Error"]
   230  			if err == lastStreamResponseError.Error() {
   231  				pool.Release(psock)
   232  				continue
   233  			}
   234  		}
   235  
   236  		// got an existing socket already
   237  		if ok {
   238  			// we're starting processing
   239  			wg.Add(1)
   240  
   241  			// pass the message to that existing socket
   242  			if err := psock.Accept(&msg); err != nil {
   243  				// release the socket if there's an error
   244  				pool.Release(psock)
   245  			}
   246  
   247  			// done waiting
   248  			wg.Done()
   249  
   250  			// continue to the next message
   251  			continue
   252  		}
   253  
   254  		// no socket was found so its new
   255  		// set the local and remote values
   256  		psock.SetLocal(sock.Local())
   257  		psock.SetRemote(sock.Remote())
   258  
   259  		// load the socket with the current message
   260  		psock.Accept(&msg)
   261  
   262  		// now walk the usual path
   263  
   264  		// we use this Timeout header to set a server deadline
   265  		to := msg.Header["Timeout"]
   266  		// we use this Content-Type header to identify the codec needed
   267  		ct := msg.Header["Content-Type"]
   268  
   269  		// copy the message headers
   270  		hdr := make(map[string]string, len(msg.Header))
   271  		for k, v := range msg.Header {
   272  			hdr[k] = v
   273  		}
   274  
   275  		// set local/remote ips
   276  		hdr["Local"] = sock.Local()
   277  		hdr["Remote"] = sock.Remote()
   278  
   279  		// create new context with the metadata
   280  		ctx := metadata.NewContext(context.Background(), hdr)
   281  
   282  		// set the timeout from the header if we have it
   283  		if len(to) > 0 {
   284  			if n, err := strconv.ParseUint(to, 10, 64); err == nil {
   285  				var cancel context.CancelFunc
   286  				ctx, cancel = context.WithTimeout(ctx, time.Duration(n))
   287  				defer cancel()
   288  			}
   289  		}
   290  
   291  		// if there's no content type default it
   292  		if len(ct) == 0 {
   293  			msg.Header["Content-Type"] = DefaultContentType
   294  			ct = DefaultContentType
   295  		}
   296  
   297  		// setup old protocol
   298  		cf := setupProtocol(&msg)
   299  
   300  		// no legacy codec needed
   301  		if cf == nil {
   302  			var err error
   303  			// try get a new codec
   304  			if cf, err = s.newCodec(ct); err != nil {
   305  				// no codec found so send back an error
   306  				if err := sock.Send(&transport.Message{
   307  					Header: map[string]string{
   308  						"Content-Type": "text/plain",
   309  					},
   310  					Body: []byte(err.Error()),
   311  				}); err != nil {
   312  					gerr = err
   313  				}
   314  
   315  				// release the socket we just created
   316  				pool.Release(psock)
   317  				// now continue
   318  				continue
   319  			}
   320  		}
   321  
   322  		// create a new rpc codec based on the pseudo socket and codec
   323  		rcodec := newRpcCodec(&msg, psock, cf)
   324  		// check the protocol as well
   325  		protocol := rcodec.String()
   326  
   327  		// internal request
   328  		request := &rpcRequest{
   329  			service:     getHeader("Micro-Service", msg.Header),
   330  			method:      getHeader("Micro-Method", msg.Header),
   331  			endpoint:    getHeader("Micro-Endpoint", msg.Header),
   332  			contentType: ct,
   333  			codec:       rcodec,
   334  			header:      msg.Header,
   335  			body:        msg.Body,
   336  			socket:      psock,
   337  			stream:      stream,
   338  		}
   339  
   340  		// internal response
   341  		response := &rpcResponse{
   342  			header: make(map[string]string),
   343  			socket: psock,
   344  			codec:  rcodec,
   345  		}
   346  
   347  		// set router
   348  		r := Router(s.router)
   349  
   350  		// if not nil use the router specified
   351  		if s.opts.Router != nil {
   352  			// create a wrapped function
   353  			handler := func(ctx context.Context, req Request, rsp interface{}) error {
   354  				return s.opts.Router.ServeRequest(ctx, req, rsp.(Response))
   355  			}
   356  
   357  			// execute the wrapper for it
   358  			for i := len(s.opts.HdlrWrappers); i > 0; i-- {
   359  				handler = s.opts.HdlrWrappers[i-1](handler)
   360  			}
   361  
   362  			// set the router
   363  			r = rpcRouter{h: handler}
   364  		}
   365  
   366  		// wait for two coroutines to exit
   367  		// serve the request and process the outbound messages
   368  		wg.Add(2)
   369  
   370  		// process the outbound messages from the socket
   371  		go func(id string, psock *socket.Socket) {
   372  			defer func() {
   373  				// TODO: don't hack this but if its grpc just break out of the stream
   374  				// We do this because the underlying connection is h2 and its a stream
   375  				switch protocol {
   376  				case "grpc":
   377  					sock.Close()
   378  				}
   379  				// release the socket
   380  				pool.Release(psock)
   381  				// signal we're done
   382  				wg.Done()
   383  
   384  				// recover any panics for outbound process
   385  				if r := recover(); r != nil {
   386  					if logger.V(logger.ErrorLevel, log) {
   387  						log.Error("panic recovered: ", r)
   388  						log.Error(string(debug.Stack()))
   389  					}
   390  				}
   391  			}()
   392  
   393  			for {
   394  				// get the message from our internal handler/stream
   395  				m := new(transport.Message)
   396  				if err := psock.Process(m); err != nil {
   397  					return
   398  				}
   399  
   400  				// send the message back over the socket
   401  				if err := sock.Send(m); err != nil {
   402  					return
   403  				}
   404  			}
   405  		}(id, psock)
   406  
   407  		// serve the request in a go routine as this may be a stream
   408  		go func(id string, psock *socket.Socket) {
   409  			defer func() {
   410  				// release the socket
   411  				pool.Release(psock)
   412  				// signal we're done
   413  				wg.Done()
   414  
   415  				// recover any panics for call handler
   416  				if r := recover(); r != nil {
   417  					log.Error("panic recovered: ", r)
   418  					log.Error(string(debug.Stack()))
   419  				}
   420  			}()
   421  
   422  			// serve the actual request using the request router
   423  			if serveRequestError := r.ServeRequest(ctx, request, response); serveRequestError != nil {
   424  				// write an error response
   425  				writeError := rcodec.Write(&codec.Message{
   426  					Header: msg.Header,
   427  					Error:  serveRequestError.Error(),
   428  					Type:   codec.Error,
   429  				}, nil)
   430  
   431  				// if the server request is an EOS error we let the socket know
   432  				// sometimes the socket is already closed on the other side, so we can ignore that error
   433  				alreadyClosed := serveRequestError == lastStreamResponseError && writeError == io.EOF
   434  
   435  				// could not write error response
   436  				if writeError != nil && !alreadyClosed {
   437  					log.Debugf("rpc: unable to write error response: %v", writeError)
   438  				}
   439  			}
   440  		}(id, psock)
   441  	}
   442  }
   443  
   444  func (s *rpcServer) newCodec(contentType string) (codec.NewCodec, error) {
   445  	if cf, ok := s.opts.Codecs[contentType]; ok {
   446  		return cf, nil
   447  	}
   448  	if cf, ok := DefaultCodecs[contentType]; ok {
   449  		return cf, nil
   450  	}
   451  	return nil, fmt.Errorf("Unsupported Content-Type: %s", contentType)
   452  }
   453  
   454  func (s *rpcServer) Options() Options {
   455  	s.RLock()
   456  	opts := s.opts
   457  	s.RUnlock()
   458  	return opts
   459  }
   460  
   461  func (s *rpcServer) Init(opts ...Option) error {
   462  	s.Lock()
   463  	defer s.Unlock()
   464  
   465  	for _, opt := range opts {
   466  		opt(&s.opts)
   467  	}
   468  	// update router if its the default
   469  	if s.opts.Router == nil {
   470  		r := newRpcRouter()
   471  		r.hdlrWrappers = s.opts.HdlrWrappers
   472  		r.serviceMap = s.router.serviceMap
   473  		r.subWrappers = s.opts.SubWrappers
   474  		s.router = r
   475  	}
   476  
   477  	s.rsvc = nil
   478  
   479  	return nil
   480  }
   481  
   482  func (s *rpcServer) NewHandler(h interface{}, opts ...HandlerOption) Handler {
   483  	return s.router.NewHandler(h, opts...)
   484  }
   485  
   486  func (s *rpcServer) Handle(h Handler) error {
   487  	s.Lock()
   488  	defer s.Unlock()
   489  
   490  	if err := s.router.Handle(h); err != nil {
   491  		return err
   492  	}
   493  
   494  	s.handlers[h.Name()] = h
   495  
   496  	return nil
   497  }
   498  
   499  func (s *rpcServer) NewSubscriber(topic string, sb interface{}, opts ...SubscriberOption) Subscriber {
   500  	return s.router.NewSubscriber(topic, sb, opts...)
   501  }
   502  
   503  func (s *rpcServer) Subscribe(sb Subscriber) error {
   504  	s.Lock()
   505  	defer s.Unlock()
   506  
   507  	if err := s.router.Subscribe(sb); err != nil {
   508  		return err
   509  	}
   510  
   511  	s.subscribers[sb] = nil
   512  	return nil
   513  }
   514  
   515  func (s *rpcServer) Register() error {
   516  	s.RLock()
   517  	rsvc := s.rsvc
   518  	config := s.Options()
   519  	s.RUnlock()
   520  
   521  	regFunc := func(service *registry.Service) error {
   522  		// create registry options
   523  		rOpts := []registry.RegisterOption{registry.RegisterTTL(config.RegisterTTL)}
   524  
   525  		var regErr error
   526  
   527  		for i := 0; i < 3; i++ {
   528  			// attempt to register
   529  			if err := config.Registry.Register(service, rOpts...); err != nil {
   530  				// set the error
   531  				regErr = err
   532  				// backoff then retry
   533  				time.Sleep(backoff.Do(i + 1))
   534  				continue
   535  			}
   536  			// success so nil error
   537  			regErr = nil
   538  			break
   539  		}
   540  
   541  		return regErr
   542  	}
   543  
   544  	// have we registered before?
   545  	if rsvc != nil {
   546  		if err := regFunc(rsvc); err != nil {
   547  			return err
   548  		}
   549  		return nil
   550  	}
   551  
   552  	var err error
   553  	var advt, host, port string
   554  	var cacheService bool
   555  
   556  	// check the advertise address first
   557  	// if it exists then use it, otherwise
   558  	// use the address
   559  	if len(config.Advertise) > 0 {
   560  		advt = config.Advertise
   561  	} else {
   562  		advt = config.Address
   563  	}
   564  
   565  	if cnt := strings.Count(advt, ":"); cnt >= 1 {
   566  		// ipv6 address in format [host]:port or ipv4 host:port
   567  		host, port, err = net.SplitHostPort(advt)
   568  		if err != nil {
   569  			return err
   570  		}
   571  	} else {
   572  		host = advt
   573  	}
   574  
   575  	if ip := net.ParseIP(host); ip != nil {
   576  		cacheService = true
   577  	}
   578  
   579  	addr, err := addr.Extract(host)
   580  	if err != nil {
   581  		return err
   582  	}
   583  
   584  	// make copy of metadata
   585  	md := metadata.Copy(config.Metadata)
   586  
   587  	// mq-rpc(eg. nats) doesn't need the port. its addr is queue name.
   588  	if port != "" {
   589  		addr = mnet.HostPort(addr, port)
   590  	}
   591  
   592  	// register service
   593  	node := &registry.Node{
   594  		Id:       config.Name + "-" + config.Id,
   595  		Address:  addr,
   596  		Metadata: md,
   597  	}
   598  
   599  	node.Metadata["transport"] = config.Transport.String()
   600  	node.Metadata["broker"] = config.Broker.String()
   601  	node.Metadata["server"] = s.String()
   602  	node.Metadata["registry"] = config.Registry.String()
   603  	node.Metadata["protocol"] = "mucp"
   604  
   605  	s.RLock()
   606  
   607  	// Maps are ordered randomly, sort the keys for consistency
   608  	var handlerList []string
   609  	for n, e := range s.handlers {
   610  		// Only advertise non internal handlers
   611  		if !e.Options().Internal {
   612  			handlerList = append(handlerList, n)
   613  		}
   614  	}
   615  
   616  	sort.Strings(handlerList)
   617  
   618  	var subscriberList []Subscriber
   619  	for e := range s.subscribers {
   620  		// Only advertise non internal subscribers
   621  		if !e.Options().Internal {
   622  			subscriberList = append(subscriberList, e)
   623  		}
   624  	}
   625  
   626  	sort.Slice(subscriberList, func(i, j int) bool {
   627  		return subscriberList[i].Topic() > subscriberList[j].Topic()
   628  	})
   629  
   630  	endpoints := make([]*registry.Endpoint, 0, len(handlerList)+len(subscriberList))
   631  
   632  	for _, n := range handlerList {
   633  		endpoints = append(endpoints, s.handlers[n].Endpoints()...)
   634  	}
   635  
   636  	for _, e := range subscriberList {
   637  		endpoints = append(endpoints, e.Endpoints()...)
   638  	}
   639  
   640  	service := &registry.Service{
   641  		Name:      config.Name,
   642  		Version:   config.Version,
   643  		Nodes:     []*registry.Node{node},
   644  		Endpoints: endpoints,
   645  	}
   646  
   647  	// get registered value
   648  	registered := s.registered
   649  
   650  	s.RUnlock()
   651  
   652  	if !registered {
   653  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   654  			log.Infof("Registry [%s] Registering node: %s", config.Registry.String(), node.Id)
   655  		}
   656  	}
   657  
   658  	// register the service
   659  	if err := regFunc(service); err != nil {
   660  		return err
   661  	}
   662  
   663  	// already registered? don't need to register subscribers
   664  	if registered {
   665  		return nil
   666  	}
   667  
   668  	s.Lock()
   669  	defer s.Unlock()
   670  
   671  	// set what we're advertising
   672  	s.opts.Advertise = addr
   673  
   674  	// router can exchange messages
   675  	if s.opts.Router != nil {
   676  		// subscribe to the topic with own name
   677  		sub, err := s.opts.Broker.Subscribe(config.Name, s.HandleEvent)
   678  		if err != nil {
   679  			return err
   680  		}
   681  
   682  		// save the subscriber
   683  		s.subscriber = sub
   684  	}
   685  
   686  	// subscribe for all of the subscribers
   687  	for sb := range s.subscribers {
   688  		var opts []broker.SubscribeOption
   689  		if queue := sb.Options().Queue; len(queue) > 0 {
   690  			opts = append(opts, broker.Queue(queue))
   691  		}
   692  
   693  		if cx := sb.Options().Context; cx != nil {
   694  			opts = append(opts, broker.SubscribeContext(cx))
   695  		}
   696  
   697  		if !sb.Options().AutoAck {
   698  			opts = append(opts, broker.DisableAutoAck())
   699  		}
   700  
   701  		sub, err := config.Broker.Subscribe(sb.Topic(), s.HandleEvent, opts...)
   702  		if err != nil {
   703  			return err
   704  		}
   705  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   706  			log.Infof("Subscribing to topic: %s", sub.Topic())
   707  		}
   708  		s.subscribers[sb] = []broker.Subscriber{sub}
   709  	}
   710  	if cacheService {
   711  		s.rsvc = service
   712  	}
   713  	s.registered = true
   714  
   715  	return nil
   716  }
   717  
   718  func (s *rpcServer) Deregister() error {
   719  	var err error
   720  	var advt, host, port string
   721  
   722  	s.RLock()
   723  	config := s.Options()
   724  	s.RUnlock()
   725  
   726  	// check the advertise address first
   727  	// if it exists then use it, otherwise
   728  	// use the address
   729  	if len(config.Advertise) > 0 {
   730  		advt = config.Advertise
   731  	} else {
   732  		advt = config.Address
   733  	}
   734  
   735  	if cnt := strings.Count(advt, ":"); cnt >= 1 {
   736  		// ipv6 address in format [host]:port or ipv4 host:port
   737  		host, port, err = net.SplitHostPort(advt)
   738  		if err != nil {
   739  			return err
   740  		}
   741  	} else {
   742  		host = advt
   743  	}
   744  
   745  	addr, err := addr.Extract(host)
   746  	if err != nil {
   747  		return err
   748  	}
   749  
   750  	// mq-rpc(eg. nats) doesn't need the port. its addr is queue name.
   751  	if port != "" {
   752  		addr = mnet.HostPort(addr, port)
   753  	}
   754  
   755  	node := &registry.Node{
   756  		Id:      config.Name + "-" + config.Id,
   757  		Address: addr,
   758  	}
   759  
   760  	service := &registry.Service{
   761  		Name:    config.Name,
   762  		Version: config.Version,
   763  		Nodes:   []*registry.Node{node},
   764  	}
   765  
   766  	if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   767  		log.Infof("Registry [%s] Deregistering node: %s", config.Registry.String(), node.Id)
   768  	}
   769  	if err := config.Registry.Deregister(service); err != nil {
   770  		return err
   771  	}
   772  
   773  	s.Lock()
   774  	s.rsvc = nil
   775  
   776  	if !s.registered {
   777  		s.Unlock()
   778  		return nil
   779  	}
   780  
   781  	s.registered = false
   782  
   783  	// close the subscriber
   784  	if s.subscriber != nil {
   785  		s.subscriber.Unsubscribe()
   786  		s.subscriber = nil
   787  	}
   788  
   789  	for sb, subs := range s.subscribers {
   790  		for _, sub := range subs {
   791  			if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   792  				log.Infof("Unsubscribing %s from topic: %s", node.Id, sub.Topic())
   793  			}
   794  			sub.Unsubscribe()
   795  		}
   796  		s.subscribers[sb] = nil
   797  	}
   798  
   799  	s.Unlock()
   800  	return nil
   801  }
   802  
   803  func (s *rpcServer) Start() error {
   804  	s.RLock()
   805  	if s.started {
   806  		s.RUnlock()
   807  		return nil
   808  	}
   809  	s.RUnlock()
   810  
   811  	config := s.Options()
   812  
   813  	// start listening on the transport
   814  	ts, err := config.Transport.Listen(config.Address)
   815  	if err != nil {
   816  		return err
   817  	}
   818  
   819  	if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   820  		log.Infof("Transport [%s] Listening on %s", config.Transport.String(), ts.Addr())
   821  	}
   822  
   823  	// swap address
   824  	s.Lock()
   825  	addr := s.opts.Address
   826  	s.opts.Address = ts.Addr()
   827  	s.Unlock()
   828  
   829  	bname := config.Broker.String()
   830  
   831  	// connect to the broker
   832  	if err := config.Broker.Connect(); err != nil {
   833  		if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   834  			log.Errorf("Broker [%s] connect error: %v", bname, err)
   835  		}
   836  		return err
   837  	}
   838  
   839  	if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   840  		log.Infof("Broker [%s] Connected to %s", bname, config.Broker.Address())
   841  	}
   842  
   843  	// use RegisterCheck func before register
   844  	if err = s.opts.RegisterCheck(s.opts.Context); err != nil {
   845  		if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   846  			log.Errorf("Server %s-%s register check error: %s", config.Name, config.Id, err)
   847  		}
   848  	} else {
   849  		// announce self to the world
   850  		if err = s.Register(); err != nil {
   851  			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   852  				log.Errorf("Server %s-%s register error: %s", config.Name, config.Id, err)
   853  			}
   854  		}
   855  	}
   856  
   857  	exit := make(chan bool)
   858  
   859  	go func() {
   860  		for {
   861  			// listen for connections
   862  			err := ts.Accept(s.ServeConn)
   863  
   864  			// TODO: listen for messages
   865  			// msg := broker.Exchange(service).Consume()
   866  
   867  			select {
   868  			// check if we're supposed to exit
   869  			case <-exit:
   870  				return
   871  			// check the error and backoff
   872  			default:
   873  				if err != nil {
   874  					if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   875  						log.Errorf("Accept error: %v", err)
   876  					}
   877  					time.Sleep(time.Second)
   878  					continue
   879  				}
   880  			}
   881  
   882  			// no error just exit
   883  			return
   884  		}
   885  	}()
   886  
   887  	go func() {
   888  		t := new(time.Ticker)
   889  
   890  		// only process if it exists
   891  		if s.opts.RegisterInterval > time.Duration(0) {
   892  			// new ticker
   893  			t = time.NewTicker(s.opts.RegisterInterval)
   894  		}
   895  
   896  		// return error chan
   897  		var ch chan error
   898  
   899  	Loop:
   900  		for {
   901  			select {
   902  			// register self on interval
   903  			case <-t.C:
   904  				s.RLock()
   905  				registered := s.registered
   906  				s.RUnlock()
   907  				rerr := s.opts.RegisterCheck(s.opts.Context)
   908  				if rerr != nil && registered {
   909  					if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   910  						log.Errorf("Server %s-%s register check error: %s, deregister it", config.Name, config.Id, err)
   911  					}
   912  					// deregister self in case of error
   913  					if err := s.Deregister(); err != nil {
   914  						if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   915  							log.Errorf("Server %s-%s deregister error: %s", config.Name, config.Id, err)
   916  						}
   917  					}
   918  				} else if rerr != nil && !registered {
   919  					if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   920  						log.Errorf("Server %s-%s register check error: %s", config.Name, config.Id, err)
   921  					}
   922  					continue
   923  				}
   924  				if err := s.Register(); err != nil {
   925  					if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   926  						log.Errorf("Server %s-%s register error: %s", config.Name, config.Id, err)
   927  					}
   928  				}
   929  			// wait for exit
   930  			case ch = <-s.exit:
   931  				t.Stop()
   932  				close(exit)
   933  				break Loop
   934  			}
   935  		}
   936  
   937  		s.RLock()
   938  		registered := s.registered
   939  		s.RUnlock()
   940  		if registered {
   941  			// deregister self
   942  			if err := s.Deregister(); err != nil {
   943  				if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   944  					log.Errorf("Server %s-%s deregister error: %s", config.Name, config.Id, err)
   945  				}
   946  			}
   947  		}
   948  
   949  		s.Lock()
   950  		swg := s.wg
   951  		s.Unlock()
   952  
   953  		// wait for requests to finish
   954  		if swg != nil {
   955  			swg.Wait()
   956  		}
   957  
   958  		// close transport listener
   959  		ch <- ts.Close()
   960  
   961  		if logger.V(logger.InfoLevel, logger.DefaultLogger) {
   962  			log.Infof("Broker [%s] Disconnected from %s", bname, config.Broker.Address())
   963  		}
   964  		// disconnect the broker
   965  		if err := config.Broker.Disconnect(); err != nil {
   966  			if logger.V(logger.ErrorLevel, logger.DefaultLogger) {
   967  				log.Errorf("Broker [%s] Disconnect error: %v", bname, err)
   968  			}
   969  		}
   970  
   971  		// swap back address
   972  		s.Lock()
   973  		s.opts.Address = addr
   974  		s.Unlock()
   975  	}()
   976  
   977  	// mark the server as started
   978  	s.Lock()
   979  	s.started = true
   980  	s.Unlock()
   981  
   982  	return nil
   983  }
   984  
   985  func (s *rpcServer) Stop() error {
   986  	s.RLock()
   987  	if !s.started {
   988  		s.RUnlock()
   989  		return nil
   990  	}
   991  	s.RUnlock()
   992  
   993  	ch := make(chan error)
   994  	s.exit <- ch
   995  
   996  	err := <-ch
   997  	s.Lock()
   998  	s.started = false
   999  	s.Unlock()
  1000  
  1001  	return err
  1002  }
  1003  
  1004  func (s *rpcServer) String() string {
  1005  	return "mucp"
  1006  }