register/noop: add noop register #306
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"go.unistack.org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
|
"go.unistack.org/micro/v3/register"
|
||||||
"go.unistack.org/micro/v3/util/id"
|
"go.unistack.org/micro/v3/util/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ var (
|
|||||||
|
|
||||||
type node struct {
|
type node struct {
|
||||||
LastSeen time.Time
|
LastSeen time.Time
|
||||||
*Node
|
*register.Node
|
||||||
TTL time.Duration
|
TTL time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,23 +26,23 @@ type record struct {
|
|||||||
Version string
|
Version string
|
||||||
Metadata map[string]string
|
Metadata map[string]string
|
||||||
Nodes map[string]*node
|
Nodes map[string]*node
|
||||||
Endpoints []*Endpoint
|
Endpoints []*register.Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
type memory struct {
|
type memory struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
records map[string]services
|
records map[string]services
|
||||||
watchers map[string]*watcher
|
watchers map[string]*watcher
|
||||||
opts Options
|
opts register.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
// services is a KV map with service name as the key and a map of records as the value
|
// services is a KV map with service name as the key and a map of records as the value
|
||||||
type services map[string]map[string]*record
|
type services map[string]map[string]*record
|
||||||
|
|
||||||
// NewRegister returns an initialized in-memory register
|
// NewRegister returns an initialized in-memory register
|
||||||
func NewRegister(opts ...Option) Register {
|
func NewRegister(opts ...register.Option) register.Register {
|
||||||
r := &memory{
|
r := &memory{
|
||||||
opts: NewOptions(opts...),
|
opts: register.NewOptions(opts...),
|
||||||
records: make(map[string]services),
|
records: make(map[string]services),
|
||||||
watchers: make(map[string]*watcher),
|
watchers: make(map[string]*watcher),
|
||||||
}
|
}
|
||||||
@ -75,7 +76,7 @@ func (m *memory) ttlPrune() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) sendEvent(r *Result) {
|
func (m *memory) sendEvent(r *register.Result) {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
watchers := make([]*watcher, 0, len(m.watchers))
|
watchers := make([]*watcher, 0, len(m.watchers))
|
||||||
for _, w := range m.watchers {
|
for _, w := range m.watchers {
|
||||||
@ -106,7 +107,7 @@ func (m *memory) Disconnect(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) Init(opts ...Option) error {
|
func (m *memory) Init(opts ...register.Option) error {
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(&m.opts)
|
o(&m.opts)
|
||||||
}
|
}
|
||||||
@ -118,15 +119,15 @@ func (m *memory) Init(opts ...Option) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) Options() Options {
|
func (m *memory) Options() register.Options {
|
||||||
return m.opts
|
return m.opts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) Register(ctx context.Context, s *Service, opts ...RegisterOption) error {
|
func (m *memory) Register(ctx context.Context, s *register.Service, opts ...register.RegisterOption) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
options := NewRegisterOptions(opts...)
|
options := register.NewRegisterOptions(opts...)
|
||||||
|
|
||||||
// get the services for this domain from the register
|
// get the services for this domain from the register
|
||||||
srvs, ok := m.records[options.Domain]
|
srvs, ok := m.records[options.Domain]
|
||||||
@ -153,7 +154,7 @@ func (m *memory) Register(ctx context.Context, s *Service, opts ...RegisterOptio
|
|||||||
m.opts.Logger.Debugf(m.opts.Context, "Register added new service: %s, version: %s", s.Name, s.Version)
|
m.opts.Logger.Debugf(m.opts.Context, "Register added new service: %s, version: %s", s.Name, s.Version)
|
||||||
}
|
}
|
||||||
m.records[options.Domain] = srvs
|
m.records[options.Domain] = srvs
|
||||||
go m.sendEvent(&Result{Action: "create", Service: s})
|
go m.sendEvent(®ister.Result{Action: "create", Service: s})
|
||||||
}
|
}
|
||||||
|
|
||||||
var addedNodes bool
|
var addedNodes bool
|
||||||
@ -176,7 +177,7 @@ func (m *memory) Register(ctx context.Context, s *Service, opts ...RegisterOptio
|
|||||||
|
|
||||||
// add the node
|
// add the node
|
||||||
srvs[s.Name][s.Version].Nodes[n.ID] = &node{
|
srvs[s.Name][s.Version].Nodes[n.ID] = &node{
|
||||||
Node: &Node{
|
Node: ®ister.Node{
|
||||||
ID: n.ID,
|
ID: n.ID,
|
||||||
Address: n.Address,
|
Address: n.Address,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
@ -192,7 +193,7 @@ func (m *memory) Register(ctx context.Context, s *Service, opts ...RegisterOptio
|
|||||||
if m.opts.Logger.V(logger.DebugLevel) {
|
if m.opts.Logger.V(logger.DebugLevel) {
|
||||||
m.opts.Logger.Debugf(m.opts.Context, "Register added new node to service: %s, version: %s", s.Name, s.Version)
|
m.opts.Logger.Debugf(m.opts.Context, "Register added new node to service: %s, version: %s", s.Name, s.Version)
|
||||||
}
|
}
|
||||||
go m.sendEvent(&Result{Action: "update", Service: s})
|
go m.sendEvent(®ister.Result{Action: "update", Service: s})
|
||||||
} else {
|
} else {
|
||||||
// refresh TTL and timestamp
|
// refresh TTL and timestamp
|
||||||
for _, n := range s.Nodes {
|
for _, n := range s.Nodes {
|
||||||
@ -208,11 +209,11 @@ func (m *memory) Register(ctx context.Context, s *Service, opts ...RegisterOptio
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) Deregister(ctx context.Context, s *Service, opts ...DeregisterOption) error {
|
func (m *memory) Deregister(ctx context.Context, s *register.Service, opts ...register.DeregisterOption) error {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
options := NewDeregisterOptions(opts...)
|
options := register.NewDeregisterOptions(opts...)
|
||||||
|
|
||||||
// domain is set in metadata so it can be passed to watchers
|
// domain is set in metadata so it can be passed to watchers
|
||||||
if s.Metadata == nil {
|
if s.Metadata == nil {
|
||||||
@ -252,7 +253,7 @@ func (m *memory) Deregister(ctx context.Context, s *Service, opts ...DeregisterO
|
|||||||
// is cleanup
|
// is cleanup
|
||||||
if len(version.Nodes) > 0 {
|
if len(version.Nodes) > 0 {
|
||||||
m.records[options.Domain][s.Name][s.Version] = version
|
m.records[options.Domain][s.Name][s.Version] = version
|
||||||
go m.sendEvent(&Result{Action: "update", Service: s})
|
go m.sendEvent(®ister.Result{Action: "update", Service: s})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +261,7 @@ func (m *memory) Deregister(ctx context.Context, s *Service, opts ...DeregisterO
|
|||||||
// register and exit
|
// register and exit
|
||||||
if len(versions) == 1 {
|
if len(versions) == 1 {
|
||||||
delete(m.records[options.Domain], s.Name)
|
delete(m.records[options.Domain], s.Name)
|
||||||
go m.sendEvent(&Result{Action: "delete", Service: s})
|
go m.sendEvent(®ister.Result{Action: "delete", Service: s})
|
||||||
|
|
||||||
if m.opts.Logger.V(logger.DebugLevel) {
|
if m.opts.Logger.V(logger.DebugLevel) {
|
||||||
m.opts.Logger.Debugf(m.opts.Context, "Register removed service: %s", s.Name)
|
m.opts.Logger.Debugf(m.opts.Context, "Register removed service: %s", s.Name)
|
||||||
@ -270,7 +271,7 @@ func (m *memory) Deregister(ctx context.Context, s *Service, opts ...DeregisterO
|
|||||||
|
|
||||||
// there are other versions of the service running, so only remove this version of it
|
// there are other versions of the service running, so only remove this version of it
|
||||||
delete(m.records[options.Domain][s.Name], s.Version)
|
delete(m.records[options.Domain][s.Name], s.Version)
|
||||||
go m.sendEvent(&Result{Action: "delete", Service: s})
|
go m.sendEvent(®ister.Result{Action: "delete", Service: s})
|
||||||
if m.opts.Logger.V(logger.DebugLevel) {
|
if m.opts.Logger.V(logger.DebugLevel) {
|
||||||
m.opts.Logger.Debugf(m.opts.Context, "Register removed service: %s, version: %s", s.Name, s.Version)
|
m.opts.Logger.Debugf(m.opts.Context, "Register removed service: %s, version: %s", s.Name, s.Version)
|
||||||
}
|
}
|
||||||
@ -278,20 +279,20 @@ func (m *memory) Deregister(ctx context.Context, s *Service, opts ...DeregisterO
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) LookupService(ctx context.Context, name string, opts ...LookupOption) ([]*Service, error) {
|
func (m *memory) LookupService(ctx context.Context, name string, opts ...register.LookupOption) ([]*register.Service, error) {
|
||||||
options := NewLookupOptions(opts...)
|
options := register.NewLookupOptions(opts...)
|
||||||
|
|
||||||
// if it's a wildcard domain, return from all domains
|
// if it's a wildcard domain, return from all domains
|
||||||
if options.Domain == WildcardDomain {
|
if options.Domain == register.WildcardDomain {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
recs := m.records
|
recs := m.records
|
||||||
m.RUnlock()
|
m.RUnlock()
|
||||||
|
|
||||||
var services []*Service
|
var services []*register.Service
|
||||||
|
|
||||||
for domain := range recs {
|
for domain := range recs {
|
||||||
srvs, err := m.LookupService(ctx, name, append(opts, LookupDomain(domain))...)
|
srvs, err := m.LookupService(ctx, name, append(opts, register.LookupDomain(domain))...)
|
||||||
if err == ErrNotFound {
|
if err == register.ErrNotFound {
|
||||||
continue
|
continue
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -300,7 +301,7 @@ func (m *memory) LookupService(ctx context.Context, name string, opts ...LookupO
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(services) == 0 {
|
if len(services) == 0 {
|
||||||
return nil, ErrNotFound
|
return nil, register.ErrNotFound
|
||||||
}
|
}
|
||||||
return services, nil
|
return services, nil
|
||||||
}
|
}
|
||||||
@ -311,17 +312,17 @@ func (m *memory) LookupService(ctx context.Context, name string, opts ...LookupO
|
|||||||
// check the domain exists
|
// check the domain exists
|
||||||
services, ok := m.records[options.Domain]
|
services, ok := m.records[options.Domain]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrNotFound
|
return nil, register.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the service exists
|
// check the service exists
|
||||||
versions, ok := services[name]
|
versions, ok := services[name]
|
||||||
if !ok || len(versions) == 0 {
|
if !ok || len(versions) == 0 {
|
||||||
return nil, ErrNotFound
|
return nil, register.ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize the response
|
// serialize the response
|
||||||
result := make([]*Service, len(versions))
|
result := make([]*register.Service, len(versions))
|
||||||
|
|
||||||
var i int
|
var i int
|
||||||
|
|
||||||
@ -333,19 +334,19 @@ func (m *memory) LookupService(ctx context.Context, name string, opts ...LookupO
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) ListServices(ctx context.Context, opts ...ListOption) ([]*Service, error) {
|
func (m *memory) ListServices(ctx context.Context, opts ...register.ListOption) ([]*register.Service, error) {
|
||||||
options := NewListOptions(opts...)
|
options := register.NewListOptions(opts...)
|
||||||
|
|
||||||
// if it's a wildcard domain, list from all domains
|
// if it's a wildcard domain, list from all domains
|
||||||
if options.Domain == WildcardDomain {
|
if options.Domain == register.WildcardDomain {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
recs := m.records
|
recs := m.records
|
||||||
m.RUnlock()
|
m.RUnlock()
|
||||||
|
|
||||||
var services []*Service
|
var services []*register.Service
|
||||||
|
|
||||||
for domain := range recs {
|
for domain := range recs {
|
||||||
srvs, err := m.ListServices(ctx, append(opts, ListDomain(domain))...)
|
srvs, err := m.ListServices(ctx, append(opts, register.ListDomain(domain))...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -361,11 +362,11 @@ func (m *memory) ListServices(ctx context.Context, opts ...ListOption) ([]*Servi
|
|||||||
// ensure the domain exists
|
// ensure the domain exists
|
||||||
services, ok := m.records[options.Domain]
|
services, ok := m.records[options.Domain]
|
||||||
if !ok {
|
if !ok {
|
||||||
return make([]*Service, 0), nil
|
return make([]*register.Service, 0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize the result, each version counts as an individual service
|
// serialize the result, each version counts as an individual service
|
||||||
var result []*Service
|
var result []*register.Service
|
||||||
|
|
||||||
for _, service := range services {
|
for _, service := range services {
|
||||||
for _, version := range service {
|
for _, version := range service {
|
||||||
@ -376,16 +377,16 @@ func (m *memory) ListServices(ctx context.Context, opts ...ListOption) ([]*Servi
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *memory) Watch(ctx context.Context, opts ...WatchOption) (Watcher, error) {
|
func (m *memory) Watch(ctx context.Context, opts ...register.WatchOption) (register.Watcher, error) {
|
||||||
id, err := id.New()
|
id, err := id.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
wo := NewWatchOptions(opts...)
|
wo := register.NewWatchOptions(opts...)
|
||||||
// construct the watcher
|
// construct the watcher
|
||||||
w := &watcher{
|
w := &watcher{
|
||||||
exit: make(chan bool),
|
exit: make(chan bool),
|
||||||
res: make(chan *Result),
|
res: make(chan *register.Result),
|
||||||
id: id,
|
id: id,
|
||||||
wo: wo,
|
wo: wo,
|
||||||
}
|
}
|
||||||
@ -406,13 +407,13 @@ func (m *memory) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type watcher struct {
|
type watcher struct {
|
||||||
res chan *Result
|
res chan *register.Result
|
||||||
exit chan bool
|
exit chan bool
|
||||||
wo WatchOptions
|
wo register.WatchOptions
|
||||||
id string
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *watcher) Next() (*Result, error) {
|
func (m *watcher) Next() (*register.Result, error) {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case r := <-m.res:
|
case r := <-m.res:
|
||||||
@ -429,15 +430,15 @@ func (m *watcher) Next() (*Result, error) {
|
|||||||
if r.Service.Metadata != nil && len(r.Service.Metadata["domain"]) > 0 {
|
if r.Service.Metadata != nil && len(r.Service.Metadata["domain"]) > 0 {
|
||||||
domain = r.Service.Metadata["domain"]
|
domain = r.Service.Metadata["domain"]
|
||||||
} else {
|
} else {
|
||||||
domain = DefaultDomain
|
domain = register.DefaultDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
// only send the event if watching the wildcard or this specific domain
|
// only send the event if watching the wildcard or this specific domain
|
||||||
if m.wo.Domain == WildcardDomain || m.wo.Domain == domain {
|
if m.wo.Domain == register.WildcardDomain || m.wo.Domain == domain {
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
case <-m.exit:
|
case <-m.exit:
|
||||||
return nil, ErrWatcherStopped
|
return nil, register.ErrWatcherStopped
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,7 +452,7 @@ func (m *watcher) Stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceToRecord(s *Service, ttl time.Duration) *record {
|
func serviceToRecord(s *register.Service, ttl time.Duration) *record {
|
||||||
metadata := make(map[string]string, len(s.Metadata))
|
metadata := make(map[string]string, len(s.Metadata))
|
||||||
for k, v := range s.Metadata {
|
for k, v := range s.Metadata {
|
||||||
metadata[k] = v
|
metadata[k] = v
|
||||||
@ -466,7 +467,7 @@ func serviceToRecord(s *Service, ttl time.Duration) *record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoints := make([]*Endpoint, len(s.Endpoints))
|
endpoints := make([]*register.Endpoint, len(s.Endpoints))
|
||||||
for i, e := range s.Endpoints {
|
for i, e := range s.Endpoints {
|
||||||
endpoints[i] = e
|
endpoints[i] = e
|
||||||
}
|
}
|
||||||
@ -480,7 +481,7 @@ func serviceToRecord(s *Service, ttl time.Duration) *record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func recordToService(r *record, domain string) *Service {
|
func recordToService(r *record, domain string) *register.Service {
|
||||||
metadata := make(map[string]string, len(r.Metadata))
|
metadata := make(map[string]string, len(r.Metadata))
|
||||||
for k, v := range r.Metadata {
|
for k, v := range r.Metadata {
|
||||||
metadata[k] = v
|
metadata[k] = v
|
||||||
@ -489,14 +490,14 @@ func recordToService(r *record, domain string) *Service {
|
|||||||
// set the domain in metadata so it can be determined when a wildcard query is performed
|
// set the domain in metadata so it can be determined when a wildcard query is performed
|
||||||
metadata["domain"] = domain
|
metadata["domain"] = domain
|
||||||
|
|
||||||
endpoints := make([]*Endpoint, len(r.Endpoints))
|
endpoints := make([]*register.Endpoint, len(r.Endpoints))
|
||||||
for i, e := range r.Endpoints {
|
for i, e := range r.Endpoints {
|
||||||
md := make(map[string]string, len(e.Metadata))
|
md := make(map[string]string, len(e.Metadata))
|
||||||
for k, v := range e.Metadata {
|
for k, v := range e.Metadata {
|
||||||
md[k] = v
|
md[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
endpoints[i] = &Endpoint{
|
endpoints[i] = ®ister.Endpoint{
|
||||||
Name: e.Name,
|
Name: e.Name,
|
||||||
Request: e.Request,
|
Request: e.Request,
|
||||||
Response: e.Response,
|
Response: e.Response,
|
||||||
@ -504,7 +505,7 @@ func recordToService(r *record, domain string) *Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes := make([]*Node, len(r.Nodes))
|
nodes := make([]*register.Node, len(r.Nodes))
|
||||||
i := 0
|
i := 0
|
||||||
for _, n := range r.Nodes {
|
for _, n := range r.Nodes {
|
||||||
md := make(map[string]string, len(n.Metadata))
|
md := make(map[string]string, len(n.Metadata))
|
||||||
@ -512,7 +513,7 @@ func recordToService(r *record, domain string) *Service {
|
|||||||
md[k] = v
|
md[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes[i] = &Node{
|
nodes[i] = ®ister.Node{
|
||||||
ID: n.ID,
|
ID: n.ID,
|
||||||
Address: n.Address,
|
Address: n.Address,
|
||||||
Metadata: md,
|
Metadata: md,
|
||||||
@ -520,7 +521,7 @@ func recordToService(r *record, domain string) *Service {
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Service{
|
return ®ister.Service{
|
||||||
Name: r.Name,
|
Name: r.Name,
|
||||||
Version: r.Version,
|
Version: r.Version,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
@ -6,14 +6,16 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.unistack.org/micro/v3/register"
|
||||||
)
|
)
|
||||||
|
|
||||||
var testData = map[string][]*Service{
|
var testData = map[string][]*register.Service{
|
||||||
"foo": {
|
"foo": {
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Version: "1.0.0",
|
Version: "1.0.0",
|
||||||
Nodes: []*Node{
|
Nodes: []*register.Node{
|
||||||
{
|
{
|
||||||
ID: "foo-1.0.0-123",
|
ID: "foo-1.0.0-123",
|
||||||
Address: "localhost:9999",
|
Address: "localhost:9999",
|
||||||
@ -27,7 +29,7 @@ var testData = map[string][]*Service{
|
|||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Version: "1.0.1",
|
Version: "1.0.1",
|
||||||
Nodes: []*Node{
|
Nodes: []*register.Node{
|
||||||
{
|
{
|
||||||
ID: "foo-1.0.1-321",
|
ID: "foo-1.0.1-321",
|
||||||
Address: "localhost:6666",
|
Address: "localhost:6666",
|
||||||
@ -37,7 +39,7 @@ var testData = map[string][]*Service{
|
|||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Version: "1.0.3",
|
Version: "1.0.3",
|
||||||
Nodes: []*Node{
|
Nodes: []*register.Node{
|
||||||
{
|
{
|
||||||
ID: "foo-1.0.3-345",
|
ID: "foo-1.0.3-345",
|
||||||
Address: "localhost:8888",
|
Address: "localhost:8888",
|
||||||
@ -49,7 +51,7 @@ var testData = map[string][]*Service{
|
|||||||
{
|
{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Version: "default",
|
Version: "default",
|
||||||
Nodes: []*Node{
|
Nodes: []*register.Node{
|
||||||
{
|
{
|
||||||
ID: "bar-1.0.0-123",
|
ID: "bar-1.0.0-123",
|
||||||
Address: "localhost:9999",
|
Address: "localhost:9999",
|
||||||
@ -63,7 +65,7 @@ var testData = map[string][]*Service{
|
|||||||
{
|
{
|
||||||
Name: "bar",
|
Name: "bar",
|
||||||
Version: "latest",
|
Version: "latest",
|
||||||
Nodes: []*Node{
|
Nodes: []*register.Node{
|
||||||
{
|
{
|
||||||
ID: "bar-1.0.1-321",
|
ID: "bar-1.0.1-321",
|
||||||
Address: "localhost:6666",
|
Address: "localhost:6666",
|
||||||
@ -78,7 +80,7 @@ func TestMemoryRegistry(t *testing.T) {
|
|||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
m := NewRegister()
|
m := NewRegister()
|
||||||
|
|
||||||
fn := func(k string, v []*Service) {
|
fn := func(k string, v []*register.Service) {
|
||||||
services, err := m.LookupService(ctx, k)
|
services, err := m.LookupService(ctx, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error getting service %s: %v", k, err)
|
t.Errorf("Unexpected error getting service %s: %v", k, err)
|
||||||
@ -155,8 +157,8 @@ func TestMemoryRegistry(t *testing.T) {
|
|||||||
for _, v := range testData {
|
for _, v := range testData {
|
||||||
for _, service := range v {
|
for _, service := range v {
|
||||||
services, err := m.LookupService(ctx, service.Name)
|
services, err := m.LookupService(ctx, service.Name)
|
||||||
if err != ErrNotFound {
|
if err != register.ErrNotFound {
|
||||||
t.Errorf("Expected error: %v, got: %v", ErrNotFound, err)
|
t.Errorf("Expected error: %v, got: %v", register.ErrNotFound, err)
|
||||||
}
|
}
|
||||||
if len(services) != 0 {
|
if len(services) != 0 {
|
||||||
t.Errorf("Expected %d services for %s, got %d", 0, service.Name, len(services))
|
t.Errorf("Expected %d services for %s, got %d", 0, service.Name, len(services))
|
||||||
@ -171,7 +173,7 @@ func TestMemoryRegistryTTL(t *testing.T) {
|
|||||||
|
|
||||||
for _, v := range testData {
|
for _, v := range testData {
|
||||||
for _, service := range v {
|
for _, service := range v {
|
||||||
if err := m.Register(ctx, service, RegisterTTL(time.Millisecond)); err != nil {
|
if err := m.Register(ctx, service, register.RegisterTTL(time.Millisecond)); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,7 +202,7 @@ func TestMemoryRegistryTTLConcurrent(t *testing.T) {
|
|||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
for _, v := range testData {
|
for _, v := range testData {
|
||||||
for _, service := range v {
|
for _, service := range v {
|
||||||
if err := m.Register(ctx, service, RegisterTTL(waitTime/2)); err != nil {
|
if err := m.Register(ctx, service, register.RegisterTTL(waitTime/2)); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,34 +251,34 @@ func TestMemoryWildcard(t *testing.T) {
|
|||||||
m := NewRegister()
|
m := NewRegister()
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
testSrv := &Service{Name: "foo", Version: "1.0.0"}
|
testSrv := ®ister.Service{Name: "foo", Version: "1.0.0"}
|
||||||
|
|
||||||
if err := m.Register(ctx, testSrv, RegisterDomain("one")); err != nil {
|
if err := m.Register(ctx, testSrv, register.RegisterDomain("one")); err != nil {
|
||||||
t.Fatalf("Register err: %v", err)
|
t.Fatalf("Register err: %v", err)
|
||||||
}
|
}
|
||||||
if err := m.Register(ctx, testSrv, RegisterDomain("two")); err != nil {
|
if err := m.Register(ctx, testSrv, register.RegisterDomain("two")); err != nil {
|
||||||
t.Fatalf("Register err: %v", err)
|
t.Fatalf("Register err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if recs, err := m.ListServices(ctx, ListDomain("one")); err != nil {
|
if recs, err := m.ListServices(ctx, register.ListDomain("one")); err != nil {
|
||||||
t.Errorf("List err: %v", err)
|
t.Errorf("List err: %v", err)
|
||||||
} else if len(recs) != 1 {
|
} else if len(recs) != 1 {
|
||||||
t.Errorf("Expected 1 record, got %v", len(recs))
|
t.Errorf("Expected 1 record, got %v", len(recs))
|
||||||
}
|
}
|
||||||
|
|
||||||
if recs, err := m.ListServices(ctx, ListDomain("*")); err != nil {
|
if recs, err := m.ListServices(ctx, register.ListDomain("*")); err != nil {
|
||||||
t.Errorf("List err: %v", err)
|
t.Errorf("List err: %v", err)
|
||||||
} else if len(recs) != 2 {
|
} else if len(recs) != 2 {
|
||||||
t.Errorf("Expected 2 records, got %v", len(recs))
|
t.Errorf("Expected 2 records, got %v", len(recs))
|
||||||
}
|
}
|
||||||
|
|
||||||
if recs, err := m.LookupService(ctx, testSrv.Name, LookupDomain("one")); err != nil {
|
if recs, err := m.LookupService(ctx, testSrv.Name, register.LookupDomain("one")); err != nil {
|
||||||
t.Errorf("Lookup err: %v", err)
|
t.Errorf("Lookup err: %v", err)
|
||||||
} else if len(recs) != 1 {
|
} else if len(recs) != 1 {
|
||||||
t.Errorf("Expected 1 record, got %v", len(recs))
|
t.Errorf("Expected 1 record, got %v", len(recs))
|
||||||
}
|
}
|
||||||
|
|
||||||
if recs, err := m.LookupService(ctx, testSrv.Name, LookupDomain("*")); err != nil {
|
if recs, err := m.LookupService(ctx, testSrv.Name, register.LookupDomain("*")); err != nil {
|
||||||
t.Errorf("Lookup err: %v", err)
|
t.Errorf("Lookup err: %v", err)
|
||||||
} else if len(recs) != 2 {
|
} else if len(recs) != 2 {
|
||||||
t.Errorf("Expected 2 records, got %v", len(recs))
|
t.Errorf("Expected 2 records, got %v", len(recs))
|
||||||
@ -284,7 +286,7 @@ func TestMemoryWildcard(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestWatcher(t *testing.T) {
|
func TestWatcher(t *testing.T) {
|
||||||
testSrv := &Service{Name: "foo", Version: "1.0.0"}
|
testSrv := ®ister.Service{Name: "foo", Version: "1.0.0"}
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
m := NewRegister()
|
m := NewRegister()
|
72
register/noop.go
Normal file
72
register/noop.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package register
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
type noop struct {
|
||||||
|
opts Options
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRegister(opts ...Option) Register {
|
||||||
|
return &noop{
|
||||||
|
opts: NewOptions(opts...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Name() string {
|
||||||
|
return n.opts.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Init(opts ...Option) error {
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&n.opts)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Options() Options {
|
||||||
|
return n.opts
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Connect(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Disconnect(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Register(ctx context.Context, service *Service, option ...RegisterOption) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Deregister(ctx context.Context, service *Service, option ...DeregisterOption) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) LookupService(ctx context.Context, s string, option ...LookupOption) ([]*Service, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) ListServices(ctx context.Context, option ...ListOption) ([]*Service, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) Watch(ctx context.Context, opts ...WatchOption) (Watcher, error) {
|
||||||
|
wOpts := NewWatchOptions(opts...)
|
||||||
|
|
||||||
|
return &watcher{wo: wOpts}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *noop) String() string {
|
||||||
|
return "noop"
|
||||||
|
}
|
||||||
|
|
||||||
|
type watcher struct {
|
||||||
|
wo WatchOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *watcher) Next() (*Result, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *watcher) Stop() {}
|
142
service.go
142
service.go
@ -7,11 +7,15 @@ import (
|
|||||||
|
|
||||||
"go.unistack.org/micro/v3/broker"
|
"go.unistack.org/micro/v3/broker"
|
||||||
"go.unistack.org/micro/v3/client"
|
"go.unistack.org/micro/v3/client"
|
||||||
|
"go.unistack.org/micro/v3/codec"
|
||||||
"go.unistack.org/micro/v3/config"
|
"go.unistack.org/micro/v3/config"
|
||||||
|
"go.unistack.org/micro/v3/flow"
|
||||||
"go.unistack.org/micro/v3/logger"
|
"go.unistack.org/micro/v3/logger"
|
||||||
"go.unistack.org/micro/v3/meter"
|
"go.unistack.org/micro/v3/meter"
|
||||||
"go.unistack.org/micro/v3/register"
|
"go.unistack.org/micro/v3/register"
|
||||||
|
"go.unistack.org/micro/v3/resolver"
|
||||||
"go.unistack.org/micro/v3/router"
|
"go.unistack.org/micro/v3/router"
|
||||||
|
"go.unistack.org/micro/v3/selector"
|
||||||
"go.unistack.org/micro/v3/server"
|
"go.unistack.org/micro/v3/server"
|
||||||
"go.unistack.org/micro/v3/store"
|
"go.unistack.org/micro/v3/store"
|
||||||
"go.unistack.org/micro/v3/tracer"
|
"go.unistack.org/micro/v3/tracer"
|
||||||
@ -72,8 +76,8 @@ func RegisterSubscriber(topic string, s server.Server, h interface{}, opts ...se
|
|||||||
}
|
}
|
||||||
|
|
||||||
type service struct {
|
type service struct {
|
||||||
sync.RWMutex
|
|
||||||
opts Options
|
opts Options
|
||||||
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewService creates and returns a new Service based on the packages within.
|
// NewService creates and returns a new Service based on the packages within.
|
||||||
@ -377,69 +381,95 @@ func (s *service) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getNameIndex(n string, ifaces interface{}) int {
|
func getNameIndex(n string, ifaces interface{}) int {
|
||||||
switch values := ifaces.(type) {
|
type namer interface {
|
||||||
case []router.Router:
|
Name() string
|
||||||
for idx, iface := range values {
|
}
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
switch vt := ifaces.(type) {
|
||||||
}
|
|
||||||
}
|
|
||||||
case []register.Register:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []store.Store:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []tracer.Tracer:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []server.Server:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []config.Config:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []meter.Meter:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case []broker.Broker:
|
case []broker.Broker:
|
||||||
for idx, iface := range values {
|
for idx, iface := range vt {
|
||||||
if iface.Name() == n {
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case []client.Client:
|
case []client.Client:
|
||||||
for idx, iface := range values {
|
for idx, iface := range vt {
|
||||||
if iface.Name() == n {
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []codec.Codec:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []config.Config:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []flow.Flow:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []logger.Logger:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []meter.Meter:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []register.Register:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []resolver.Resolver:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []router.Router:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []selector.Selector:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []server.Server:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []store.Store:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
|
return idx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case []tracer.Tracer:
|
||||||
|
for idx, iface := range vt {
|
||||||
|
if nm, ok := iface.(namer); ok && nm.Name() == n {
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
case []logger.Logger:
|
|
||||||
for idx, iface := range values {
|
|
||||||
if iface.Name() == n {
|
|
||||||
return idx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -22,13 +22,14 @@ func TestClient(t *testing.T) {
|
|||||||
c2 := client.NewClient(client.Name("test2"))
|
c2 := client.NewClient(client.Name("test2"))
|
||||||
|
|
||||||
svc := NewService(Client(c1, c2))
|
svc := NewService(Client(c1, c2))
|
||||||
|
|
||||||
if err := svc.Init(); err != nil {
|
if err := svc.Init(); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
x1 := svc.Client("test2")
|
x1 := svc.Client("test2")
|
||||||
if x1.Name() != "test2" {
|
if x1.Name() != "test2" {
|
||||||
t.Fatal("invalid client")
|
t.Fatalf("invalid client %#+v", svc.Options().Clients)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,15 +41,6 @@ func (ti *testItem) Name() string {
|
|||||||
return ti.name
|
return ti.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetNameIndex(t *testing.T) {
|
|
||||||
item1 := &testItem{name: "first"}
|
|
||||||
item2 := &testItem{name: "second"}
|
|
||||||
items := []interface{}{item1, item2}
|
|
||||||
if idx := getNameIndex("second", items); idx != 1 {
|
|
||||||
t.Fatalf("getNameIndex func error, item not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRegisterHandler(t *testing.T) {
|
func TestRegisterHandler(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
s server.Server
|
s server.Server
|
||||||
|
Loading…
Reference in New Issue
Block a user