Merge pull request 'register: improvements' (#390) from register into v3
Reviewed-on: #390
This commit is contained in:
		
							
								
								
									
										6
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.mod
									
									
									
									
									
								
							| @@ -1,12 +1,12 @@ | |||||||
| module go.unistack.org/micro/v3 | module go.unistack.org/micro/v3 | ||||||
|  |  | ||||||
| go 1.22.2 | go 1.22.0 | ||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	dario.cat/mergo v1.0.1 | 	dario.cat/mergo v1.0.1 | ||||||
| 	github.com/DATA-DOG/go-sqlmock v1.5.0 | 	github.com/DATA-DOG/go-sqlmock v1.5.2 | ||||||
| 	github.com/KimMachineGun/automemlimit v0.6.1 | 	github.com/KimMachineGun/automemlimit v0.6.1 | ||||||
| 	github.com/ash3in/uuidv8 v1.0.1 | 	github.com/ash3in/uuidv8 v1.2.0 | ||||||
| 	github.com/google/uuid v1.6.0 | 	github.com/google/uuid v1.6.0 | ||||||
| 	github.com/matoous/go-nanoid v1.5.1 | 	github.com/matoous/go-nanoid v1.5.1 | ||||||
| 	github.com/patrickmn/go-cache v2.1.0+incompatible | 	github.com/patrickmn/go-cache v2.1.0+incompatible | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								go.sum
									
									
									
									
									
								
							| @@ -1,11 +1,11 @@ | |||||||
| dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= | dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= | ||||||
| dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= | dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= | ||||||
| github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= | github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU= | ||||||
| github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= | github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= | ||||||
| github.com/KimMachineGun/automemlimit v0.6.1 h1:ILa9j1onAAMadBsyyUJv5cack8Y1WT26yLj/V+ulKp8= | github.com/KimMachineGun/automemlimit v0.6.1 h1:ILa9j1onAAMadBsyyUJv5cack8Y1WT26yLj/V+ulKp8= | ||||||
| github.com/KimMachineGun/automemlimit v0.6.1/go.mod h1:T7xYht7B8r6AG/AqFcUdc7fzd2bIdBKmepfP2S1svPY= | github.com/KimMachineGun/automemlimit v0.6.1/go.mod h1:T7xYht7B8r6AG/AqFcUdc7fzd2bIdBKmepfP2S1svPY= | ||||||
| github.com/ash3in/uuidv8 v1.0.1 h1:dIq1XRkWT8lGA7N5s7WRTB4V3k49WTBLvILz7aCLp80= | github.com/ash3in/uuidv8 v1.2.0 h1:2oogGdtCPwaVtyvPPGin4TfZLtOGE5F+W++E880G6SI= | ||||||
| github.com/ash3in/uuidv8 v1.0.1/go.mod h1:EoyUgCtxNBnrnpc9efw5rVN1cQ+LFGCoJiFuD6maOMw= | github.com/ash3in/uuidv8 v1.2.0/go.mod h1:BnU0wJBxnzdEKmVg4xckBkD+VZuecTFTUP3M0dWgyY4= | ||||||
| github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= | github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= | ||||||
| github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= | github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= | ||||||
| github.com/containerd/cgroups/v3 v3.0.4 h1:2fs7l3P0Qxb1nKWuJNFiwhp2CqiKzho71DQkDrHJIo4= | github.com/containerd/cgroups/v3 v3.0.4 h1:2fs7l3P0Qxb1nKWuJNFiwhp2CqiKzho71DQkDrHJIo4= | ||||||
| @@ -35,6 +35,7 @@ github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtL | |||||||
| github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= | github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= | ||||||
| github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= | github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= | ||||||
| github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= | github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= | ||||||
|  | github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= | ||||||
| github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||||||
| github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= | ||||||
| github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= | ||||||
|   | |||||||
| @@ -16,6 +16,25 @@ import ( | |||||||
| 	"go.unistack.org/micro/v3/metadata" | 	"go.unistack.org/micro/v3/metadata" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | // always first to have proper check | ||||||
|  | func TestStacktrace(t *testing.T) { | ||||||
|  | 	ctx := context.TODO() | ||||||
|  | 	buf := bytes.NewBuffer(nil) | ||||||
|  | 	l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), | ||||||
|  | 		WithHandlerFunc(slog.NewTextHandler), | ||||||
|  | 		logger.WithAddStacktrace(true), | ||||||
|  | 	) | ||||||
|  | 	if err := l.Init(logger.WithFields("key1", "val1")); err != nil { | ||||||
|  | 		t.Fatal(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	l.Error(ctx, "msg1", errors.New("err")) | ||||||
|  |  | ||||||
|  | 	if !bytes.Contains(buf.Bytes(), []byte(`slog_test.go:31`)) { | ||||||
|  | 		t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| func TestTime(t *testing.T) { | func TestTime(t *testing.T) { | ||||||
| 	ctx := context.TODO() | 	ctx := context.TODO() | ||||||
| 	buf := bytes.NewBuffer(nil) | 	buf := bytes.NewBuffer(nil) | ||||||
| @@ -32,25 +51,8 @@ func TestTime(t *testing.T) { | |||||||
|  |  | ||||||
| 	l.Error(ctx, "msg1", errors.New("err")) | 	l.Error(ctx, "msg1", errors.New("err")) | ||||||
|  |  | ||||||
| 	if !bytes.Contains(buf.Bytes(), []byte(`timestamp=1970-01-01T03:00:00.000000000+03:00`)) { | 	if !bytes.Contains(buf.Bytes(), []byte(`timestamp=1970-01-01T03:00:00.000000000+03:00`)) && | ||||||
| 		t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) | 		!bytes.Contains(buf.Bytes(), []byte(`timestamp=1970-01-01T00:00:00.000000000Z`)) { | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestStacktrace(t *testing.T) { |  | ||||||
| 	ctx := context.TODO() |  | ||||||
| 	buf := bytes.NewBuffer(nil) |  | ||||||
| 	l := NewLogger(logger.WithLevel(logger.ErrorLevel), logger.WithOutput(buf), |  | ||||||
| 		WithHandlerFunc(slog.NewTextHandler), |  | ||||||
| 		logger.WithAddStacktrace(true), |  | ||||||
| 	) |  | ||||||
| 	if err := l.Init(logger.WithFields("key1", "val1")); err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	l.Error(ctx, "msg1", errors.New("err")) |  | ||||||
|  |  | ||||||
| 	if !bytes.Contains(buf.Bytes(), []byte(`slog_test.go:51`)) { |  | ||||||
| 		t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) | 		t.Fatalf("logger error not works, buf contains: %s", buf.Bytes()) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,12 +1,9 @@ | |||||||
| package register | package register | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" |  | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"unicode" | 	"unicode" | ||||||
| 	"unicode/utf8" | 	"unicode/utf8" | ||||||
|  |  | ||||||
| 	"go.unistack.org/micro/v3/metadata" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // ExtractValue from reflect.Type from specified depth | // ExtractValue from reflect.Type from specified depth | ||||||
| @@ -38,53 +35,6 @@ func ExtractValue(v reflect.Type, d int) string { | |||||||
| 	return v.Name() | 	return v.Name() | ||||||
| } | } | ||||||
|  |  | ||||||
| // ExtractEndpoint extract *Endpoint from reflect.Method |  | ||||||
| func ExtractEndpoint(method reflect.Method) *Endpoint { |  | ||||||
| 	if method.PkgPath != "" { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	var rspType, reqType reflect.Type |  | ||||||
| 	var stream bool |  | ||||||
| 	mt := method.Type |  | ||||||
|  |  | ||||||
| 	switch mt.NumIn() { |  | ||||||
| 	case 3: |  | ||||||
| 		reqType = mt.In(1) |  | ||||||
| 		rspType = mt.In(2) |  | ||||||
| 	case 4: |  | ||||||
| 		reqType = mt.In(2) |  | ||||||
| 		rspType = mt.In(3) |  | ||||||
| 	default: |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// are we dealing with a stream? |  | ||||||
| 	switch rspType.Kind() { |  | ||||||
| 	case reflect.Func, reflect.Interface: |  | ||||||
| 		stream = true |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	request := ExtractValue(reqType, 0) |  | ||||||
| 	response := ExtractValue(rspType, 0) |  | ||||||
| 	if request == "" || response == "" { |  | ||||||
| 		return nil |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ep := &Endpoint{ |  | ||||||
| 		Name:     method.Name, |  | ||||||
| 		Request:  request, |  | ||||||
| 		Response: response, |  | ||||||
| 		Metadata: metadata.New(0), |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if stream { |  | ||||||
| 		ep.Metadata.Set("stream", fmt.Sprintf("%v", stream)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return ep |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ExtractSubValue exctact *Value from reflect.Type | // ExtractSubValue exctact *Value from reflect.Type | ||||||
| func ExtractSubValue(typ reflect.Type) string { | func ExtractSubValue(typ reflect.Type) string { | ||||||
| 	var reqType reflect.Type | 	var reqType reflect.Type | ||||||
|   | |||||||
| @@ -2,8 +2,6 @@ package register | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"reflect" |  | ||||||
| 	"testing" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| type TestHandler struct{} | type TestHandler struct{} | ||||||
| @@ -15,40 +13,3 @@ type TestResponse struct{} | |||||||
| func (t *TestHandler) Test(ctx context.Context, req *TestRequest, rsp *TestResponse) error { | func (t *TestHandler) Test(ctx context.Context, req *TestRequest, rsp *TestResponse) error { | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestExtractEndpoint(t *testing.T) { |  | ||||||
| 	handler := &TestHandler{} |  | ||||||
| 	typ := reflect.TypeOf(handler) |  | ||||||
|  |  | ||||||
| 	var endpoints []*Endpoint |  | ||||||
|  |  | ||||||
| 	for m := 0; m < typ.NumMethod(); m++ { |  | ||||||
| 		if e := ExtractEndpoint(typ.Method(m)); e != nil { |  | ||||||
| 			endpoints = append(endpoints, e) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if i := len(endpoints); i != 1 { |  | ||||||
| 		t.Fatalf("Expected 1 endpoint, have %d", i) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if endpoints[0].Name != "Test" { |  | ||||||
| 		t.Fatalf("Expected handler Test, got %s", endpoints[0].Name) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if endpoints[0].Request == "" { |  | ||||||
| 		t.Fatal("Expected non nil Request") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if endpoints[0].Response == "" { |  | ||||||
| 		t.Fatal("Expected non nil Request") |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if endpoints[0].Request != "TestRequest" { |  | ||||||
| 		t.Fatalf("Expected TestRequest got %s", endpoints[0].Request) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if endpoints[0].Response != "TestResponse" { |  | ||||||
| 		t.Fatalf("Expected TestResponse got %s", endpoints[0].Response) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -27,7 +27,6 @@ type record struct { | |||||||
| 	Version  string | 	Version  string | ||||||
| 	Metadata map[string]string | 	Metadata map[string]string | ||||||
| 	Nodes    map[string]*node | 	Nodes    map[string]*node | ||||||
| 	Endpoints []*register.Endpoint |  | ||||||
| } | } | ||||||
|  |  | ||||||
| type memory struct { | type memory struct { | ||||||
| @@ -59,7 +58,7 @@ func (m *memory) ttlPrune() { | |||||||
|  |  | ||||||
| 	for range prune.C { | 	for range prune.C { | ||||||
| 		m.Lock() | 		m.Lock() | ||||||
| 		for domain, services := range m.records { | 		for namespace, services := range m.records { | ||||||
| 			for service, versions := range services { | 			for service, versions := range services { | ||||||
| 				for version, record := range versions { | 				for version, record := range versions { | ||||||
| 					for id, n := range record.Nodes { | 					for id, n := range record.Nodes { | ||||||
| @@ -67,7 +66,7 @@ func (m *memory) ttlPrune() { | |||||||
| 							if m.opts.Logger.V(logger.DebugLevel) { | 							if m.opts.Logger.V(logger.DebugLevel) { | ||||||
| 								m.opts.Logger.Debug(m.opts.Context, fmt.Sprintf("Register TTL expired for node %s of service %s", n.ID, service)) | 								m.opts.Logger.Debug(m.opts.Context, fmt.Sprintf("Register TTL expired for node %s of service %s", n.ID, service)) | ||||||
| 							} | 							} | ||||||
| 							delete(m.records[domain][service][version].Nodes, id) | 							delete(m.records[namespace][service][version].Nodes, id) | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| @@ -131,17 +130,12 @@ func (m *memory) Register(_ context.Context, s *register.Service, opts ...regist | |||||||
| 	options := register.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.Namespace] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		srvs = make(services) | 		srvs = make(services) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// domain is set in metadata so it can be passed to watchers | 	s.Namespace = options.Namespace | ||||||
| 	if s.Metadata == nil { |  | ||||||
| 		s.Metadata = map[string]string{"domain": options.Domain} |  | ||||||
| 	} else { |  | ||||||
| 		s.Metadata["domain"] = options.Domain |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// ensure the service name exists | 	// ensure the service name exists | ||||||
| 	r := serviceToRecord(s, options.TTL) | 	r := serviceToRecord(s, options.TTL) | ||||||
| @@ -154,7 +148,7 @@ func (m *memory) Register(_ context.Context, s *register.Service, opts ...regist | |||||||
| 		if m.opts.Logger.V(logger.DebugLevel) { | 		if m.opts.Logger.V(logger.DebugLevel) { | ||||||
| 			m.opts.Logger.Debug(m.opts.Context, fmt.Sprintf("Register added new service: %s, version: %s", s.Name, s.Version)) | 			m.opts.Logger.Debug(m.opts.Context, fmt.Sprintf("Register added new service: %s, version: %s", s.Name, s.Version)) | ||||||
| 		} | 		} | ||||||
| 		m.records[options.Domain] = srvs | 		m.records[options.Namespace] = srvs | ||||||
| 		go m.sendEvent(®ister.Result{Action: "create", Service: s}) | 		go m.sendEvent(®ister.Result{Action: "create", Service: s}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -173,9 +167,6 @@ func (m *memory) Register(_ context.Context, s *register.Service, opts ...regist | |||||||
| 			metadata[k] = v | 			metadata[k] = v | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// set the domain |  | ||||||
| 		metadata["domain"] = options.Domain |  | ||||||
|  |  | ||||||
| 		// 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: ®ister.Node{ | 			Node: ®ister.Node{ | ||||||
| @@ -206,7 +197,7 @@ func (m *memory) Register(_ context.Context, s *register.Service, opts ...regist | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	m.records[options.Domain] = srvs | 	m.records[options.Namespace] = srvs | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -216,15 +207,8 @@ func (m *memory) Deregister(ctx context.Context, s *register.Service, opts ...re | |||||||
|  |  | ||||||
| 	options := register.NewDeregisterOptions(opts...) | 	options := register.NewDeregisterOptions(opts...) | ||||||
|  |  | ||||||
| 	// domain is set in metadata so it can be passed to watchers |  | ||||||
| 	if s.Metadata == nil { |  | ||||||
| 		s.Metadata = map[string]string{"domain": options.Domain} |  | ||||||
| 	} else { |  | ||||||
| 		s.Metadata["domain"] = options.Domain |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// if the domain doesn't exist, there is nothing to deregister | 	// if the domain doesn't exist, there is nothing to deregister | ||||||
| 	services, ok := m.records[options.Domain] | 	services, ok := m.records[options.Namespace] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -253,7 +237,7 @@ func (m *memory) Deregister(ctx context.Context, s *register.Service, opts ...re | |||||||
| 	// if the nodes not empty, we replace the version in the store and exist, the rest of the logic | 	// if the nodes not empty, we replace the version in the store and exist, the rest of the logic | ||||||
| 	// 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.Namespace][s.Name][s.Version] = version | ||||||
| 		go m.sendEvent(®ister.Result{Action: "update", Service: s}) | 		go m.sendEvent(®ister.Result{Action: "update", Service: s}) | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| @@ -261,7 +245,7 @@ func (m *memory) Deregister(ctx context.Context, s *register.Service, opts ...re | |||||||
| 	// if this version was the only version of the service, we can remove the whole service from the | 	// if this version was the only version of the service, we can remove the whole service from the | ||||||
| 	// 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.Namespace], s.Name) | ||||||
| 		go m.sendEvent(®ister.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) { | ||||||
| @@ -271,7 +255,7 @@ func (m *memory) Deregister(ctx context.Context, s *register.Service, opts ...re | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 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.Namespace][s.Name], s.Version) | ||||||
| 	go m.sendEvent(®ister.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.Debug(m.opts.Context, fmt.Sprintf("Register removed service: %s, version: %s", s.Name, s.Version)) | 		m.opts.Logger.Debug(m.opts.Context, fmt.Sprintf("Register removed service: %s, version: %s", s.Name, s.Version)) | ||||||
| @@ -284,15 +268,15 @@ func (m *memory) LookupService(ctx context.Context, name string, opts ...registe | |||||||
| 	options := register.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 == register.WildcardDomain { | 	if options.Namespace == register.WildcardNamespace { | ||||||
| 		m.RLock() | 		m.RLock() | ||||||
| 		recs := m.records | 		recs := m.records | ||||||
| 		m.RUnlock() | 		m.RUnlock() | ||||||
|  |  | ||||||
| 		var services []*register.Service | 		var services []*register.Service | ||||||
|  |  | ||||||
| 		for domain := range recs { | 		for namespace := range recs { | ||||||
| 			srvs, err := m.LookupService(ctx, name, append(opts, register.LookupDomain(domain))...) | 			srvs, err := m.LookupService(ctx, name, append(opts, register.LookupNamespace(namespace))...) | ||||||
| 			if err == register.ErrNotFound { | 			if err == register.ErrNotFound { | ||||||
| 				continue | 				continue | ||||||
| 			} else if err != nil { | 			} else if err != nil { | ||||||
| @@ -311,7 +295,7 @@ func (m *memory) LookupService(ctx context.Context, name string, opts ...registe | |||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
|  |  | ||||||
| 	// check the domain exists | 	// check the domain exists | ||||||
| 	services, ok := m.records[options.Domain] | 	services, ok := m.records[options.Namespace] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, register.ErrNotFound | 		return nil, register.ErrNotFound | ||||||
| 	} | 	} | ||||||
| @@ -328,7 +312,7 @@ func (m *memory) LookupService(ctx context.Context, name string, opts ...registe | |||||||
| 	var i int | 	var i int | ||||||
|  |  | ||||||
| 	for _, r := range versions { | 	for _, r := range versions { | ||||||
| 		result[i] = recordToService(r, options.Domain) | 		result[i] = recordToService(r, options.Namespace) | ||||||
| 		i++ | 		i++ | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -339,15 +323,15 @@ func (m *memory) ListServices(ctx context.Context, opts ...register.ListOption) | |||||||
| 	options := register.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 == register.WildcardDomain { | 	if options.Namespace == register.WildcardNamespace { | ||||||
| 		m.RLock() | 		m.RLock() | ||||||
| 		recs := m.records | 		recs := m.records | ||||||
| 		m.RUnlock() | 		m.RUnlock() | ||||||
|  |  | ||||||
| 		var services []*register.Service | 		var services []*register.Service | ||||||
|  |  | ||||||
| 		for domain := range recs { | 		for namespace := range recs { | ||||||
| 			srvs, err := m.ListServices(ctx, append(opts, register.ListDomain(domain))...) | 			srvs, err := m.ListServices(ctx, append(opts, register.ListNamespace(namespace))...) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, err | ||||||
| 			} | 			} | ||||||
| @@ -361,7 +345,7 @@ func (m *memory) ListServices(ctx context.Context, opts ...register.ListOption) | |||||||
| 	defer m.RUnlock() | 	defer m.RUnlock() | ||||||
|  |  | ||||||
| 	// ensure the domain exists | 	// ensure the domain exists | ||||||
| 	services, ok := m.records[options.Domain] | 	services, ok := m.records[options.Namespace] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return make([]*register.Service, 0), nil | 		return make([]*register.Service, 0), nil | ||||||
| 	} | 	} | ||||||
| @@ -371,7 +355,7 @@ func (m *memory) ListServices(ctx context.Context, opts ...register.ListOption) | |||||||
|  |  | ||||||
| 	for _, service := range services { | 	for _, service := range services { | ||||||
| 		for _, version := range service { | 		for _, version := range service { | ||||||
| 			result = append(result, recordToService(version, options.Domain)) | 			result = append(result, recordToService(version, options.Namespace)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -426,16 +410,13 @@ func (m *watcher) Next() (*register.Result, error) { | |||||||
| 				continue | 				continue | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			// extract domain from service metadata | 			namespace := register.DefaultNamespace | ||||||
| 			var domain string | 			if r.Service.Namespace != "" { | ||||||
| 			if r.Service.Metadata != nil && len(r.Service.Metadata["domain"]) > 0 { | 				namespace = r.Service.Namespace | ||||||
| 				domain = r.Service.Metadata["domain"] |  | ||||||
| 			} else { |  | ||||||
| 				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 == register.WildcardDomain || m.wo.Domain == domain { | 			if m.wo.Namespace == register.WildcardNamespace || m.wo.Namespace == namespace { | ||||||
| 				return r, nil | 				return r, nil | ||||||
| 			} | 			} | ||||||
| 		case <-m.exit: | 		case <-m.exit: | ||||||
| @@ -454,11 +435,6 @@ func (m *watcher) Stop() { | |||||||
| } | } | ||||||
|  |  | ||||||
| func serviceToRecord(s *register.Service, ttl time.Duration) *record { | func serviceToRecord(s *register.Service, ttl time.Duration) *record { | ||||||
| 	metadata := make(map[string]string, len(s.Metadata)) |  | ||||||
| 	for k, v := range s.Metadata { |  | ||||||
| 		metadata[k] = v |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	nodes := make(map[string]*node, len(s.Nodes)) | 	nodes := make(map[string]*node, len(s.Nodes)) | ||||||
| 	for _, n := range s.Nodes { | 	for _, n := range s.Nodes { | ||||||
| 		nodes[n.ID] = &node{ | 		nodes[n.ID] = &node{ | ||||||
| @@ -468,42 +444,19 @@ func serviceToRecord(s *register.Service, ttl time.Duration) *record { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	endpoints := make([]*register.Endpoint, len(s.Endpoints)) |  | ||||||
| 	copy(endpoints, s.Endpoints) |  | ||||||
|  |  | ||||||
| 	return &record{ | 	return &record{ | ||||||
| 		Name:    s.Name, | 		Name:    s.Name, | ||||||
| 		Version: s.Version, | 		Version: s.Version, | ||||||
| 		Metadata:  metadata, |  | ||||||
| 		Nodes:   nodes, | 		Nodes:   nodes, | ||||||
| 		Endpoints: endpoints, |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func recordToService(r *record, domain string) *register.Service { | func recordToService(r *record, namespace 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 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// set the domain in metadata so it can be determined when a wildcard query is performed |  | ||||||
| 	metadata["domain"] = domain |  | ||||||
|  |  | ||||||
| 	endpoints := make([]*register.Endpoint, len(r.Endpoints)) |  | ||||||
| 	for i, e := range r.Endpoints { |  | ||||||
| 		md := make(map[string]string, len(e.Metadata)) |  | ||||||
| 		for k, v := range e.Metadata { |  | ||||||
| 			md[k] = v |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		endpoints[i] = ®ister.Endpoint{ |  | ||||||
| 			Name:     e.Name, |  | ||||||
| 			Request:  e.Request, |  | ||||||
| 			Response: e.Response, |  | ||||||
| 			Metadata: md, |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	nodes := make([]*register.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 { | ||||||
| @@ -523,8 +476,7 @@ func recordToService(r *record, domain string) *register.Service { | |||||||
| 	return ®ister.Service{ | 	return ®ister.Service{ | ||||||
| 		Name:      r.Name, | 		Name:      r.Name, | ||||||
| 		Version:   r.Version, | 		Version:   r.Version, | ||||||
| 		Metadata:  metadata, |  | ||||||
| 		Endpoints: endpoints, |  | ||||||
| 		Nodes:     nodes, | 		Nodes:     nodes, | ||||||
|  | 		Namespace: namespace, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -253,32 +253,32 @@ func TestMemoryWildcard(t *testing.T) { | |||||||
|  |  | ||||||
| 	testSrv := ®ister.Service{Name: "foo", Version: "1.0.0"} | 	testSrv := ®ister.Service{Name: "foo", Version: "1.0.0"} | ||||||
|  |  | ||||||
| 	if err := m.Register(ctx, testSrv, register.RegisterDomain("one")); err != nil { | 	if err := m.Register(ctx, testSrv, register.RegisterNamespace("one")); err != nil { | ||||||
| 		t.Fatalf("Register err: %v", err) | 		t.Fatalf("Register err: %v", err) | ||||||
| 	} | 	} | ||||||
| 	if err := m.Register(ctx, testSrv, register.RegisterDomain("two")); err != nil { | 	if err := m.Register(ctx, testSrv, register.RegisterNamespace("two")); err != nil { | ||||||
| 		t.Fatalf("Register err: %v", err) | 		t.Fatalf("Register err: %v", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if recs, err := m.ListServices(ctx, register.ListDomain("one")); err != nil { | 	if recs, err := m.ListServices(ctx, register.ListNamespace("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, register.ListDomain("*")); err != nil { | 	if recs, err := m.ListServices(ctx, register.ListNamespace("*")); 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, register.LookupDomain("one")); err != nil { | 	if recs, err := m.LookupService(ctx, testSrv.Name, register.LookupNamespace("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, register.LookupDomain("*")); err != nil { | 	if recs, err := m.LookupService(ctx, testSrv.Name, register.LookupNamespace("*")); 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)) | ||||||
|   | |||||||
| @@ -47,7 +47,7 @@ func NewOptions(opts ...Option) Options { | |||||||
| // RegisterOptions holds options for register method | // RegisterOptions holds options for register method | ||||||
| type RegisterOptions struct { // nolint: golint,revive | type RegisterOptions struct { // nolint: golint,revive | ||||||
| 	Context   context.Context | 	Context   context.Context | ||||||
| 	Domain   string | 	Namespace string | ||||||
| 	TTL       time.Duration | 	TTL       time.Duration | ||||||
| 	Attempts  int | 	Attempts  int | ||||||
| } | } | ||||||
| @@ -55,7 +55,7 @@ type RegisterOptions struct { // nolint: golint,revive | |||||||
| // NewRegisterOptions returns register options struct filled by opts | // NewRegisterOptions returns register options struct filled by opts | ||||||
| func NewRegisterOptions(opts ...RegisterOption) RegisterOptions { | func NewRegisterOptions(opts ...RegisterOption) RegisterOptions { | ||||||
| 	options := RegisterOptions{ | 	options := RegisterOptions{ | ||||||
| 		Domain:  DefaultDomain, | 		Namespace: DefaultNamespace, | ||||||
| 		Context:   context.Background(), | 		Context:   context.Background(), | ||||||
| 	} | 	} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| @@ -72,14 +72,14 @@ type WatchOptions struct { | |||||||
| 	// Other options for implementations of the interface | 	// Other options for implementations of the interface | ||||||
| 	// can be stored in a context | 	// can be stored in a context | ||||||
| 	Context context.Context | 	Context context.Context | ||||||
| 	// Domain to watch | 	// Namespace to watch | ||||||
| 	Domain string | 	Namespace string | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewWatchOptions returns watch options filled by opts | // NewWatchOptions returns watch options filled by opts | ||||||
| func NewWatchOptions(opts ...WatchOption) WatchOptions { | func NewWatchOptions(opts ...WatchOption) WatchOptions { | ||||||
| 	options := WatchOptions{ | 	options := WatchOptions{ | ||||||
| 		Domain:  DefaultDomain, | 		Namespace: DefaultNamespace, | ||||||
| 		Context:   context.Background(), | 		Context:   context.Background(), | ||||||
| 	} | 	} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| @@ -91,8 +91,8 @@ func NewWatchOptions(opts ...WatchOption) WatchOptions { | |||||||
| // DeregisterOptions holds options for deregister method | // DeregisterOptions holds options for deregister method | ||||||
| type DeregisterOptions struct { | type DeregisterOptions struct { | ||||||
| 	Context context.Context | 	Context context.Context | ||||||
| 	// Domain the service was registered in | 	// Namespace the service was registered in | ||||||
| 	Domain string | 	Namespace string | ||||||
| 	// Atempts specify max attempts for deregister | 	// Atempts specify max attempts for deregister | ||||||
| 	Attempts int | 	Attempts int | ||||||
| } | } | ||||||
| @@ -100,7 +100,7 @@ type DeregisterOptions struct { | |||||||
| // NewDeregisterOptions returns options for deregister filled by opts | // NewDeregisterOptions returns options for deregister filled by opts | ||||||
| func NewDeregisterOptions(opts ...DeregisterOption) DeregisterOptions { | func NewDeregisterOptions(opts ...DeregisterOption) DeregisterOptions { | ||||||
| 	options := DeregisterOptions{ | 	options := DeregisterOptions{ | ||||||
| 		Domain:  DefaultDomain, | 		Namespace: DefaultNamespace, | ||||||
| 		Context:   context.Background(), | 		Context:   context.Background(), | ||||||
| 	} | 	} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| @@ -112,14 +112,14 @@ func NewDeregisterOptions(opts ...DeregisterOption) DeregisterOptions { | |||||||
| // LookupOptions holds lookup options | // LookupOptions holds lookup options | ||||||
| type LookupOptions struct { | type LookupOptions struct { | ||||||
| 	Context context.Context | 	Context context.Context | ||||||
| 	// Domain to scope the request to | 	// Namespace to scope the request to | ||||||
| 	Domain string | 	Namespace string | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewLookupOptions returns lookup options filled by opts | // NewLookupOptions returns lookup options filled by opts | ||||||
| func NewLookupOptions(opts ...LookupOption) LookupOptions { | func NewLookupOptions(opts ...LookupOption) LookupOptions { | ||||||
| 	options := LookupOptions{ | 	options := LookupOptions{ | ||||||
| 		Domain:  DefaultDomain, | 		Namespace: DefaultNamespace, | ||||||
| 		Context:   context.Background(), | 		Context:   context.Background(), | ||||||
| 	} | 	} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| @@ -131,14 +131,14 @@ func NewLookupOptions(opts ...LookupOption) LookupOptions { | |||||||
| // ListOptions holds the list options for list method | // ListOptions holds the list options for list method | ||||||
| type ListOptions struct { | type ListOptions struct { | ||||||
| 	Context context.Context | 	Context context.Context | ||||||
| 	// Domain to scope the request to | 	// Namespace to scope the request to | ||||||
| 	Domain string | 	Namespace string | ||||||
| } | } | ||||||
|  |  | ||||||
| // NewListOptions returns list options filled by opts | // NewListOptions returns list options filled by opts | ||||||
| func NewListOptions(opts ...ListOption) ListOptions { | func NewListOptions(opts ...ListOption) ListOptions { | ||||||
| 	options := ListOptions{ | 	options := ListOptions{ | ||||||
| 		Domain:  DefaultDomain, | 		Namespace: DefaultNamespace, | ||||||
| 		Context:   context.Background(), | 		Context:   context.Background(), | ||||||
| 	} | 	} | ||||||
| 	for _, o := range opts { | 	for _, o := range opts { | ||||||
| @@ -217,10 +217,10 @@ func RegisterContext(ctx context.Context) RegisterOption { // nolint: golint,rev | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // RegisterDomain secifies register domain | // RegisterNamespace secifies register Namespace | ||||||
| func RegisterDomain(d string) RegisterOption { // nolint: golint,revive | func RegisterNamespace(d string) RegisterOption { // nolint: golint,revive | ||||||
| 	return func(o *RegisterOptions) { | 	return func(o *RegisterOptions) { | ||||||
| 		o.Domain = d | 		o.Namespace = d | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -238,10 +238,10 @@ func WatchContext(ctx context.Context) WatchOption { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // WatchDomain sets the domain for watch | // WatchNamespace sets the Namespace for watch | ||||||
| func WatchDomain(d string) WatchOption { | func WatchNamespace(d string) WatchOption { | ||||||
| 	return func(o *WatchOptions) { | 	return func(o *WatchOptions) { | ||||||
| 		o.Domain = d | 		o.Namespace = d | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -259,10 +259,10 @@ func DeregisterContext(ctx context.Context) DeregisterOption { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // DeregisterDomain specifies deregister domain | // DeregisterNamespace specifies deregister Namespace | ||||||
| func DeregisterDomain(d string) DeregisterOption { | func DeregisterNamespace(d string) DeregisterOption { | ||||||
| 	return func(o *DeregisterOptions) { | 	return func(o *DeregisterOptions) { | ||||||
| 		o.Domain = d | 		o.Namespace = d | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -273,10 +273,10 @@ func LookupContext(ctx context.Context) LookupOption { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // LookupDomain sets the domain for lookup | // LookupNamespace sets the Namespace for lookup | ||||||
| func LookupDomain(d string) LookupOption { | func LookupNamespace(d string) LookupOption { | ||||||
| 	return func(o *LookupOptions) { | 	return func(o *LookupOptions) { | ||||||
| 		o.Domain = d | 		o.Namespace = d | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -287,10 +287,10 @@ func ListContext(ctx context.Context) ListOption { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // ListDomain sets the domain for list method | // ListNamespace sets the Namespace for list method | ||||||
| func ListDomain(d string) ListOption { | func ListNamespace(d string) ListOption { | ||||||
| 	return func(o *ListOptions) { | 	return func(o *ListOptions) { | ||||||
| 		o.Domain = d | 		o.Namespace = d | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,12 +9,12 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
| 	// WildcardDomain indicates any domain | 	// WildcardNamespace indicates any Namespace | ||||||
| 	WildcardDomain = "*" | 	WildcardNamespace = "*" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // DefaultDomain to use if none was provided in options | // DefaultNamespace to use if none was provided in options | ||||||
| var DefaultDomain = "micro" | var DefaultNamespace = "micro" | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	// DefaultRegister is the global default register | 	// DefaultRegister is the global default register | ||||||
| @@ -59,26 +59,17 @@ type Register interface { | |||||||
|  |  | ||||||
| // Service holds service register info | // Service holds service register info | ||||||
| type Service struct { | type Service struct { | ||||||
| 	Name      string            `json:"name"` | 	Name      string  `json:"name,omitempty"` | ||||||
| 	Version   string            `json:"version"` | 	Version   string  `json:"version,omitempty"` | ||||||
| 	Metadata  metadata.Metadata `json:"metadata"` | 	Nodes     []*Node `json:"nodes,omitempty"` | ||||||
| 	Endpoints []*Endpoint       `json:"endpoints"` | 	Namespace string  `json:"namespace,omitempty"` | ||||||
| 	Nodes     []*Node           `json:"nodes"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Node holds node register info | // Node holds node register info | ||||||
| type Node struct { | type Node struct { | ||||||
| 	Metadata metadata.Metadata `json:"metadata"` | 	Metadata metadata.Metadata `json:"metadata,omitempty"` | ||||||
| 	ID       string            `json:"id"` | 	ID       string            `json:"id,omitempty"` | ||||||
| 	Address  string            `json:"address"` | 	Address  string            `json:"address,omitempty"` | ||||||
| } |  | ||||||
|  |  | ||||||
| // Endpoint holds endpoint register info |  | ||||||
| type Endpoint struct { |  | ||||||
| 	Request  string            `json:"request"` |  | ||||||
| 	Response string            `json:"response"` |  | ||||||
| 	Metadata metadata.Metadata `json:"metadata"` |  | ||||||
| 	Name     string            `json:"name"` |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // Option func signature | // Option func signature | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"runtime/debug" | 	"runtime/debug" | ||||||
| 	"sort" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| @@ -35,34 +34,17 @@ type rpcHandler struct { | |||||||
| 	opts    HandlerOptions | 	opts    HandlerOptions | ||||||
| 	handler interface{} | 	handler interface{} | ||||||
| 	name    string | 	name    string | ||||||
| 	endpoints []*register.Endpoint |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func newRPCHandler(handler interface{}, opts ...HandlerOption) Handler { | func newRPCHandler(handler interface{}, opts ...HandlerOption) Handler { | ||||||
| 	options := NewHandlerOptions(opts...) | 	options := NewHandlerOptions(opts...) | ||||||
|  |  | ||||||
| 	typ := reflect.TypeOf(handler) |  | ||||||
| 	hdlr := reflect.ValueOf(handler) | 	hdlr := reflect.ValueOf(handler) | ||||||
| 	name := reflect.Indirect(hdlr).Type().Name() | 	name := reflect.Indirect(hdlr).Type().Name() | ||||||
|  |  | ||||||
| 	var endpoints []*register.Endpoint |  | ||||||
|  |  | ||||||
| 	for m := 0; m < typ.NumMethod(); m++ { |  | ||||||
| 		if e := register.ExtractEndpoint(typ.Method(m)); e != nil { |  | ||||||
| 			e.Name = name + "." + e.Name |  | ||||||
|  |  | ||||||
| 			for k, v := range options.Metadata[e.Name] { |  | ||||||
| 				e.Metadata[k] = v |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			endpoints = append(endpoints, e) |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return &rpcHandler{ | 	return &rpcHandler{ | ||||||
| 		name:    name, | 		name:    name, | ||||||
| 		handler: handler, | 		handler: handler, | ||||||
| 		endpoints: endpoints, |  | ||||||
| 		opts:    options, | 		opts:    options, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -75,10 +57,6 @@ func (r *rpcHandler) Handler() interface{} { | |||||||
| 	return r.handler | 	return r.handler | ||||||
| } | } | ||||||
|  |  | ||||||
| func (r *rpcHandler) Endpoints() []*register.Endpoint { |  | ||||||
| 	return r.endpoints |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (r *rpcHandler) Options() HandlerOptions { | func (r *rpcHandler) Options() HandlerOptions { | ||||||
| 	return r.opts | 	return r.opts | ||||||
| } | } | ||||||
| @@ -249,35 +227,6 @@ func (n *noopServer) Register() error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	n.RLock() |  | ||||||
| 	handlerList := make([]string, 0, len(n.handlers)) |  | ||||||
| 	for n := range n.handlers { |  | ||||||
| 		handlerList = append(handlerList, n) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	sort.Strings(handlerList) |  | ||||||
|  |  | ||||||
| 	subscriberList := make([]*subscriber, 0, len(n.subscribers)) |  | ||||||
| 	for e := range n.subscribers { |  | ||||||
| 		subscriberList = append(subscriberList, e) |  | ||||||
| 	} |  | ||||||
| 	sort.Slice(subscriberList, func(i, j int) bool { |  | ||||||
| 		return subscriberList[i].topic > subscriberList[j].topic |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	endpoints := make([]*register.Endpoint, 0, len(handlerList)+len(subscriberList)) |  | ||||||
| 	for _, h := range handlerList { |  | ||||||
| 		endpoints = append(endpoints, n.handlers[h].Endpoints()...) |  | ||||||
| 	} |  | ||||||
| 	for _, e := range subscriberList { |  | ||||||
| 		endpoints = append(endpoints, e.Endpoints()...) |  | ||||||
| 	} |  | ||||||
| 	n.RUnlock() |  | ||||||
|  |  | ||||||
| 	service.Nodes[0].Metadata["protocol"] = "noop" |  | ||||||
| 	service.Nodes[0].Metadata["transport"] = service.Nodes[0].Metadata["protocol"] |  | ||||||
| 	service.Endpoints = endpoints |  | ||||||
|  |  | ||||||
| 	n.RLock() | 	n.RLock() | ||||||
| 	registered := n.registered | 	registered := n.registered | ||||||
| 	n.RUnlock() | 	n.RUnlock() | ||||||
| @@ -576,7 +525,6 @@ func (n *noopServer) Stop() error { | |||||||
| } | } | ||||||
|  |  | ||||||
| func newSubscriber(topic string, sub interface{}, opts ...SubscriberOption) Subscriber { | func newSubscriber(topic string, sub interface{}, opts ...SubscriberOption) Subscriber { | ||||||
| 	var endpoints []*register.Endpoint |  | ||||||
| 	var handlers []*handler | 	var handlers []*handler | ||||||
|  |  | ||||||
| 	options := NewSubscriberOptions(opts...) | 	options := NewSubscriberOptions(opts...) | ||||||
| @@ -595,18 +543,7 @@ func newSubscriber(topic string, sub interface{}, opts ...SubscriberOption) Subs | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		handlers = append(handlers, h) | 		handlers = append(handlers, h) | ||||||
| 		ep := ®ister.Endpoint{ |  | ||||||
| 			Name:     "Func", |  | ||||||
| 			Request:  register.ExtractSubValue(typ), |  | ||||||
| 			Metadata: metadata.New(2), |  | ||||||
| 		} |  | ||||||
| 		ep.Metadata.Set("topic", topic) |  | ||||||
| 		ep.Metadata.Set("subscriber", "true") |  | ||||||
| 		endpoints = append(endpoints, ep) |  | ||||||
| 	} else { | 	} else { | ||||||
| 		hdlr := reflect.ValueOf(sub) |  | ||||||
| 		name := reflect.Indirect(hdlr).Type().Name() |  | ||||||
|  |  | ||||||
| 		for m := 0; m < typ.NumMethod(); m++ { | 		for m := 0; m < typ.NumMethod(); m++ { | ||||||
| 			method := typ.Method(m) | 			method := typ.Method(m) | ||||||
| 			h := &handler{ | 			h := &handler{ | ||||||
| @@ -622,14 +559,6 @@ func newSubscriber(topic string, sub interface{}, opts ...SubscriberOption) Subs | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			handlers = append(handlers, h) | 			handlers = append(handlers, h) | ||||||
| 			ep := ®ister.Endpoint{ |  | ||||||
| 				Name:     name + "." + method.Name, |  | ||||||
| 				Request:  register.ExtractSubValue(method.Type), |  | ||||||
| 				Metadata: metadata.New(2), |  | ||||||
| 			} |  | ||||||
| 			ep.Metadata.Set("topic", topic) |  | ||||||
| 			ep.Metadata.Set("subscriber", "true") |  | ||||||
| 			endpoints = append(endpoints, ep) |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -639,7 +568,6 @@ func newSubscriber(topic string, sub interface{}, opts ...SubscriberOption) Subs | |||||||
| 		topic:      topic, | 		topic:      topic, | ||||||
| 		subscriber: sub, | 		subscriber: sub, | ||||||
| 		handlers:   handlers, | 		handlers:   handlers, | ||||||
| 		endpoints:  endpoints, |  | ||||||
| 		opts:       options, | 		opts:       options, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -766,10 +694,6 @@ func (s *subscriber) Subscriber() interface{} { | |||||||
| 	return s.subscriber | 	return s.subscriber | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *subscriber) Endpoints() []*register.Endpoint { |  | ||||||
| 	return s.endpoints |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (s *subscriber) Options() SubscriberOptions { | func (s *subscriber) Options() SubscriberOptions { | ||||||
| 	return s.opts | 	return s.opts | ||||||
| } | } | ||||||
| @@ -780,7 +704,6 @@ type subscriber struct { | |||||||
| 	typ        reflect.Type | 	typ        reflect.Type | ||||||
| 	subscriber interface{} | 	subscriber interface{} | ||||||
|  |  | ||||||
| 	endpoints []*register.Endpoint |  | ||||||
| 	handlers []*handler | 	handlers []*handler | ||||||
|  |  | ||||||
| 	rcvr reflect.Value | 	rcvr reflect.Value | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ var ( | |||||||
|  |  | ||||||
| 		opts := []register.RegisterOption{ | 		opts := []register.RegisterOption{ | ||||||
| 			register.RegisterTTL(config.RegisterTTL), | 			register.RegisterTTL(config.RegisterTTL), | ||||||
| 			register.RegisterDomain(config.Namespace), | 			register.RegisterNamespace(config.Namespace), | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		for i := 0; i <= config.RegisterAttempts; i++ { | 		for i := 0; i <= config.RegisterAttempts; i++ { | ||||||
| @@ -36,7 +36,7 @@ var ( | |||||||
| 		var err error | 		var err error | ||||||
|  |  | ||||||
| 		opts := []register.DeregisterOption{ | 		opts := []register.DeregisterOption{ | ||||||
| 			register.DeregisterDomain(config.Namespace), | 			register.DeregisterNamespace(config.Namespace), | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		for i := 0; i <= config.DeregisterAttempts; i++ { | 		for i := 0; i <= config.DeregisterAttempts; i++ { | ||||||
| @@ -85,6 +85,5 @@ func NewRegisterService(s Server) (*register.Service, error) { | |||||||
| 		Name:    opts.Name, | 		Name:    opts.Name, | ||||||
| 		Version: opts.Version, | 		Version: opts.Version, | ||||||
| 		Nodes:   []*register.Node{node}, | 		Nodes:   []*register.Node{node}, | ||||||
| 		Metadata: metadata.New(0), |  | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,6 @@ import ( | |||||||
|  |  | ||||||
| 	"go.unistack.org/micro/v3/codec" | 	"go.unistack.org/micro/v3/codec" | ||||||
| 	"go.unistack.org/micro/v3/metadata" | 	"go.unistack.org/micro/v3/metadata" | ||||||
| 	"go.unistack.org/micro/v3/register" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // DefaultServer default server | // DefaultServer default server | ||||||
| @@ -170,7 +169,6 @@ type Stream interface { | |||||||
| type Handler interface { | type Handler interface { | ||||||
| 	Name() string | 	Name() string | ||||||
| 	Handler() interface{} | 	Handler() interface{} | ||||||
| 	Endpoints() []*register.Endpoint |  | ||||||
| 	Options() HandlerOptions | 	Options() HandlerOptions | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -180,6 +178,5 @@ type Handler interface { | |||||||
| type Subscriber interface { | type Subscriber interface { | ||||||
| 	Topic() string | 	Topic() string | ||||||
| 	Subscriber() interface{} | 	Subscriber() interface{} | ||||||
| 	Endpoints() []*register.Endpoint |  | ||||||
| 	Options() SubscriberOptions | 	Options() SubscriberOptions | ||||||
| } | } | ||||||
|   | |||||||
| @@ -71,14 +71,6 @@ func CopyService(service *register.Service) *register.Service { | |||||||
| 	} | 	} | ||||||
| 	s.Nodes = nodes | 	s.Nodes = nodes | ||||||
|  |  | ||||||
| 	// copy endpoints |  | ||||||
| 	eps := make([]*register.Endpoint, len(service.Endpoints)) |  | ||||||
| 	for j, ep := range service.Endpoints { |  | ||||||
| 		e := ®ister.Endpoint{} |  | ||||||
| 		*e = *ep |  | ||||||
| 		eps[j] = e |  | ||||||
| 	} |  | ||||||
| 	s.Endpoints = eps |  | ||||||
| 	return s | 	return s | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user