register/noop: add noop register #306

Merged
vtolstov merged 2 commits from register-noop into v3 2024-03-01 21:40:04 +03:00
5 changed files with 234 additions and 137 deletions

View File

@ -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(&register.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: &register.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(&register.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(&register.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(&register.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(&register.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] = &register.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] = &register.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 &register.Service{
Name: r.Name, Name: r.Name,
Version: r.Version, Version: r.Version,
Metadata: metadata, Metadata: metadata,

View File

@ -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 := &register.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 := &register.Service{Name: "foo", Version: "1.0.0"}
ctx := context.TODO() ctx := context.TODO()
m := NewRegister() m := NewRegister()

72
register/noop.go Normal file
View 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() {}

View File

@ -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

View File

@ -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