micro/registry/service/service.go

217 lines
5.0 KiB
Go
Raw Normal View History

2019-09-09 18:57:57 +03:00
// Package service uses the registry service
package service
import (
"context"
"time"
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/client/grpc"
"github.com/micro/go-micro/v2/errors"
"github.com/micro/go-micro/v2/registry"
pb "github.com/micro/go-micro/v2/registry/service/proto"
2019-09-09 18:57:57 +03:00
)
var (
// The default service name
DefaultService = "go.micro.registry"
2019-09-09 18:57:57 +03:00
)
type serviceRegistry struct {
opts registry.Options
// name of the registry
name string
// address
address []string
2020-05-13 15:38:13 +03:00
// client to call registry
client pb.RegistryService
2019-09-09 18:57:57 +03:00
}
func (s *serviceRegistry) callOpts() []client.CallOption {
var opts []client.CallOption
// set registry address
if len(s.address) > 0 {
opts = append(opts, client.WithAddress(s.address...))
}
// set timeout
if s.opts.Timeout > time.Duration(0) {
opts = append(opts, client.WithRequestTimeout(s.opts.Timeout))
}
return opts
}
func (s *serviceRegistry) Init(opts ...registry.Option) error {
for _, o := range opts {
o(&s.opts)
}
2020-05-13 15:13:11 +03:00
2020-05-14 20:00:13 +03:00
if len(s.opts.Addrs) > 0 {
s.address = s.opts.Addrs
}
2020-05-13 15:13:11 +03:00
// extract the client from the context, fallback to grpc
var cli client.Client
if c, ok := s.opts.Context.Value(clientKey{}).(client.Client); ok {
cli = c
} else {
cli = grpc.NewClient()
}
2020-05-13 15:38:13 +03:00
s.client = pb.NewRegistryService(DefaultService, cli)
2020-05-13 15:13:11 +03:00
2019-09-09 18:57:57 +03:00
return nil
}
func (s *serviceRegistry) Options() registry.Options {
return s.opts
}
func (s *serviceRegistry) Register(srv *registry.Service, opts ...registry.RegisterOption) error {
var options registry.RegisterOptions
for _, o := range opts {
o(&options)
}
2020-04-14 14:32:59 +03:00
if options.Context == nil {
options.Context = context.TODO()
}
2019-09-09 18:57:57 +03:00
// encode srv into protobuf and pack TTL and domain into it
pbSrv := ToProto(srv)
pbSrv.Options.Ttl = int64(options.TTL.Seconds())
pbSrv.Options.Domain = options.Domain
2019-09-09 18:57:57 +03:00
// register the service
2020-05-13 15:38:13 +03:00
_, err := s.client.Register(options.Context, pbSrv, s.callOpts()...)
return err
2019-09-09 18:57:57 +03:00
}
2020-04-14 14:32:59 +03:00
func (s *serviceRegistry) Deregister(srv *registry.Service, opts ...registry.DeregisterOption) error {
var options registry.DeregisterOptions
for _, o := range opts {
o(&options)
}
if options.Context == nil {
options.Context = context.TODO()
}
// encode srv into protobuf and pack domain into it
pbSrv := ToProto(srv)
pbSrv.Options.Domain = options.Domain
2019-09-09 18:57:57 +03:00
// deregister the service
_, err := s.client.Deregister(options.Context, pbSrv, s.callOpts()...)
return err
2019-09-09 18:57:57 +03:00
}
2020-04-14 14:32:59 +03:00
func (s *serviceRegistry) GetService(name string, opts ...registry.GetOption) ([]*registry.Service, error) {
var options registry.GetOptions
for _, o := range opts {
o(&options)
}
if options.Context == nil {
options.Context = context.TODO()
}
2020-05-13 15:38:13 +03:00
rsp, err := s.client.GetService(options.Context, &pb.GetRequest{
Service: name, Options: &pb.Options{Domain: options.Domain},
2019-09-09 18:57:57 +03:00
}, s.callOpts()...)
if verr, ok := err.(*errors.Error); ok && verr.Code == 404 {
return nil, registry.ErrNotFound
} else if err != nil {
2019-09-09 18:57:57 +03:00
return nil, err
}
services := make([]*registry.Service, 0, len(rsp.Services))
2019-09-09 18:57:57 +03:00
for _, service := range rsp.Services {
2019-09-09 19:20:17 +03:00
services = append(services, ToService(service))
2019-09-09 18:57:57 +03:00
}
return services, nil
}
2020-04-14 14:32:59 +03:00
func (s *serviceRegistry) ListServices(opts ...registry.ListOption) ([]*registry.Service, error) {
var options registry.ListOptions
for _, o := range opts {
o(&options)
}
if options.Context == nil {
options.Context = context.TODO()
}
req := &pb.ListRequest{Options: &pb.Options{Domain: options.Domain}}
rsp, err := s.client.ListServices(options.Context, req, s.callOpts()...)
2019-09-09 18:57:57 +03:00
if err != nil {
return nil, err
}
services := make([]*registry.Service, 0, len(rsp.Services))
2019-09-09 18:57:57 +03:00
for _, service := range rsp.Services {
2019-09-09 19:20:17 +03:00
services = append(services, ToService(service))
2019-09-09 18:57:57 +03:00
}
return services, nil
}
func (s *serviceRegistry) Watch(opts ...registry.WatchOption) (registry.Watcher, error) {
var options registry.WatchOptions
for _, o := range opts {
o(&options)
}
2020-04-14 14:32:59 +03:00
if options.Context == nil {
options.Context = context.TODO()
}
2019-09-09 18:57:57 +03:00
2020-05-13 15:38:13 +03:00
stream, err := s.client.Watch(options.Context, &pb.WatchRequest{
Service: options.Service, Options: &pb.Options{Domain: options.Domain},
2019-09-09 18:57:57 +03:00
}, s.callOpts()...)
if err != nil {
return nil, err
}
return newWatcher(stream), nil
}
func (s *serviceRegistry) String() string {
return "service"
2019-09-09 18:57:57 +03:00
}
// NewRegistry returns a new registry service client
func NewRegistry(opts ...registry.Option) registry.Registry {
var options registry.Options
for _, o := range opts {
o(&options)
}
2019-09-25 13:09:19 +03:00
// the registry address
addrs := options.Addrs
if len(addrs) == 0 {
addrs = []string{"127.0.0.1:8000"}
}
2020-05-13 15:13:11 +03:00
if options.Context == nil {
options.Context = context.TODO()
}
2019-09-09 18:57:57 +03:00
2020-05-13 15:13:11 +03:00
// extract the client from the context, fallback to grpc
var cli client.Client
if c, ok := options.Context.Value(clientKey{}).(client.Client); ok {
cli = c
} else {
cli = grpc.NewClient()
}
2019-09-09 18:57:57 +03:00
2020-05-13 15:13:11 +03:00
// service name. TODO: accept option
2019-09-09 18:57:57 +03:00
name := DefaultService
return &serviceRegistry{
2020-05-13 15:38:13 +03:00
opts: options,
name: name,
address: addrs,
client: pb.NewRegistryService(name, cli),
2019-09-09 18:57:57 +03:00
}
}