package grpc import ( "github.com/micro/go-micro/v2/client" gclient "github.com/micro/go-micro/v2/client/grpc" "github.com/micro/go-micro/v2/model" "github.com/micro/go-micro/v2/server" gserver "github.com/micro/go-micro/v2/server/grpc" "github.com/micro/go-micro/v2/service" ) type grpcService struct { opts service.Options } func newService(opts ...service.Option) service.Service { options := service.NewOptions(opts...) return &grpcService{ opts: options, } } func (s *grpcService) Name() string { return s.opts.Server.Options().Name } // Init initialises options. Additionally it calls cmd.Init // which parses command line flags. cmd.Init is only called // on first Init. func (s *grpcService) Init(opts ...service.Option) { // process options for _, o := range opts { o(&s.opts) } } func (s *grpcService) Options() service.Options { return s.opts } func (s *grpcService) Client() client.Client { return s.opts.Client } func (s *grpcService) Server() server.Server { return s.opts.Server } func (s *grpcService) Model() model.Model { return s.opts.Model } func (s *grpcService) String() string { return "grpc" } func (s *grpcService) Start() error { for _, fn := range s.opts.BeforeStart { if err := fn(); err != nil { return err } } if err := s.opts.Server.Start(); err != nil { return err } for _, fn := range s.opts.AfterStart { if err := fn(); err != nil { return err } } return nil } func (s *grpcService) Stop() error { var gerr error for _, fn := range s.opts.BeforeStop { if err := fn(); err != nil { gerr = err } } if err := s.opts.Server.Stop(); err != nil { return err } for _, fn := range s.opts.AfterStop { if err := fn(); err != nil { gerr = err } } return gerr } func (s *grpcService) Run() error { if err := s.Start(); err != nil { return err } // wait on context cancel <-s.opts.Context.Done() return s.Stop() } // NewService returns a grpc service compatible with go-micro.Service func NewService(opts ...service.Option) service.Service { // our grpc client c := gclient.NewClient() // our grpc server s := gserver.NewServer() // create options with priority for our opts options := []service.Option{ service.Client(c), service.Server(s), } // append passed in opts options = append(options, opts...) // generate and return a service return newService(options...) }