Repository: go-kratos/kratos
Pull request #2185 (2022-07-11 09:58:54)

style(contrib/registry/*) annotation perfect
完善contrib/registry 模块代码注释


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 4d65cdad..3794a7c0 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -36,7 +36,7 @@ jobs:
           - "8848:8848"
           - "9848:9848"
       polaris:
-        image: polarismesh/polaris-server-standalone:latest
+        image: polarismesh/polaris-server-standalone:v1.9.0
         ports:
           - 8090:8090
           - 8091:8091
diff --git a/contrib/registry/eureka/client.go b/contrib/registry/eureka/client.go
index 5895a057..64cdddec 100644
--- a/contrib/registry/eureka/client.go
+++ b/contrib/registry/eureka/client.go
@@ -37,7 +37,7 @@ type Endpoint struct {
 	MetaData       map[string]string
 }
 
-// Response for /eureka/apps
+// ApplicationsRootResponse for /eureka/apps
 type ApplicationsRootResponse struct {
 	ApplicationsResponse `json:"applications"`
 }
diff --git a/contrib/registry/eureka/register.go b/contrib/registry/eureka/register.go
index 31727242..62ee81cf 100644
--- a/contrib/registry/eureka/register.go
+++ b/contrib/registry/eureka/register.go
@@ -59,7 +59,7 @@ func New(eurekaUrls []string, opts ...Option) (*Registry, error) {
 	return r, nil
 }
 
-// 这里的Context是每个注册器独享的
+// Register 这里的Context是每个注册器独享的
 func (r *Registry) Register(ctx context.Context, service *registry.ServiceInstance) error {
 	return r.api.Register(ctx, service.Name, r.Endpoints(service)...)
 }
@@ -86,7 +86,7 @@ func (r *Registry) GetService(ctx context.Context, serviceName string) ([]*regis
 	return items, nil
 }
 
-// watch 是独立的ctx
+// Watch 是独立的ctx
 func (r *Registry) Watch(ctx context.Context, serviceName string) (registry.Watcher, error) {
 	return newWatch(ctx, r.api, serviceName)
 }
diff --git a/contrib/registry/kubernetes/registry.go b/contrib/registry/kubernetes/registry.go
index e8aaa169..bd752bc1 100644
--- a/contrib/registry/kubernetes/registry.go
+++ b/contrib/registry/kubernetes/registry.go
@@ -1,4 +1,4 @@
-// The package registry simply implements the Kubernetes-based Registry
+// Package kuberegistry registry simply implements the Kubernetes-based Registry
 package kuberegistry
 
 import (
@@ -78,7 +78,7 @@ const (
 	AnnotationsKeyProtocolMap = "kratos-service-protocols"
 )
 
-// The registry simply implements service discovery based on Kubernetes
+// The Registry simply implements service discovery based on Kubernetes
 // It has not been verified in the production environment and is currently for reference only
 type Registry struct {
 	clientSet       *kubernetes.Clientset
@@ -156,7 +156,7 @@ func (s *Registry) Deregister(ctx context.Context, service *registry.ServiceInst
 	})
 }
 
-// Service return the service instances in memory according to the service name.
+// GetService return the service instances in memory according to the service name.
 func (s *Registry) GetService(ctx context.Context, name string) ([]*registry.ServiceInstance, error) {
 	pods, err := s.podLister.List(labels.SelectorFromSet(map[string]string{
 		LabelsKeyServiceName: name,
@@ -258,7 +258,7 @@ func GetNamespace() string {
 	return currentNamespace
 }
 
-// GetNamespace is used to get the name of the Pod where the current container is located
+// GetPodName is used to get the name of the Pod where the current container is located
 func GetPodName() string {
 	return os.Getenv("HOSTNAME")
 }
diff --git a/transport/grpc/server.go b/transport/grpc/server.go
index 0131692e..2b5bde74 100644
--- a/transport/grpc/server.go
+++ b/transport/grpc/server.go
@@ -199,13 +199,14 @@ func (s *Server) listenAndEndpoint() error {
 			s.err = err
 			return err
 		}
-		addr, err := host.Extract(s.address, lis)
+		s.lis = lis
+	}
+	if s.endpoint == nil {
+		addr, err := host.Extract(s.address, s.lis)
 		if err != nil {
-			_ = s.lis.Close()
 			s.err = err
 			return err
 		}
-		s.lis = lis
 		s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("grpc", s.tlsConf != nil), addr)
 	}
 	return s.err
diff --git a/transport/http/router.go b/transport/http/router.go
index d8d5c08e..1575ff11 100644
--- a/transport/http/router.go
+++ b/transport/http/router.go
@@ -6,6 +6,15 @@ import (
 	"sync"
 )
 
+// WalkRouteFunc is the type of the function called for each route visited by Walk.
+type WalkRouteFunc func(RouteInfo) error
+
+// RouteInfo is an HTTP route info.
+type RouteInfo struct {
+	Path   string
+	Method string
+}
+
 // HandlerFunc defines a function to serve HTTP requests.
 type HandlerFunc func(Context) error
 
diff --git a/transport/http/server.go b/transport/http/server.go
index a0d4f14f..9bb9ffea 100644
--- a/transport/http/server.go
+++ b/transport/http/server.go
@@ -157,6 +157,26 @@ func NewServer(opts ...ServerOption) *Server {
 	return srv
 }
 
+// WalkRoute walks the router and all its sub-routers, calling walkFn for each route in the tree.
+func (s *Server) WalkRoute(fn WalkRouteFunc) error {
+	return s.router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
+		methods, err := route.GetMethods()
+		if err != nil {
+			return nil // ignore no methods
+		}
+		path, err := route.GetPathTemplate()
+		if err != nil {
+			return err
+		}
+		for _, method := range methods {
+			if err := fn(RouteInfo{Method: method, Path: path}); err != nil {
+				return err
+			}
+		}
+		return nil
+	})
+}
+
 // Route registers an HTTP router.
 func (s *Server) Route(prefix string, filters ...FilterFunc) *Router {
 	return newRouter(prefix, s, filters...)
@@ -268,13 +288,14 @@ func (s *Server) listenAndEndpoint() error {
 			s.err = err
 			return err
 		}
-		addr, err := host.Extract(s.address, lis)
+		s.lis = lis
+	}
+	if s.endpoint == nil {
+		addr, err := host.Extract(s.address, s.lis)
 		if err != nil {
-			_ = s.lis.Close()
 			s.err = err
 			return err
 		}
-		s.lis = lis
 		s.endpoint = endpoint.NewEndpoint(endpoint.Scheme("http", s.tlsConf != nil), addr)
 	}
 	return s.err


Test patch:
diff --git a/transport/grpc/server_test.go b/transport/grpc/server_test.go
index 3a8141c2..368c3295 100644
--- a/transport/grpc/server_test.go
+++ b/transport/grpc/server_test.go
@@ -289,10 +289,16 @@ func TestServer_unaryServerInterceptor(t *testing.T) {
 }
 
 func TestListener(t *testing.T) {
-	lis := &net.TCPListener{}
+	lis, err := net.Listen("tcp", ":0")
+	if err != nil {
+		t.Fatal(err)
+	}
 	s := &Server{}
 	Listener(lis)(s)
 	if !reflect.DeepEqual(lis, s.lis) {
 		t.Errorf("expect %v, got %v", lis, s.lis)
 	}
+	if e, err := s.Endpoint(); err != nil || e == nil {
+		t.Errorf("expect not empty")
+	}
 }
diff --git a/transport/http/server_test.go b/transport/http/server_test.go
index ea60d0cf..a6f05080 100644
--- a/transport/http/server_test.go
+++ b/transport/http/server_test.go
@@ -19,6 +19,10 @@ import (
 	"github.com/go-kratos/kratos/v2/internal/host"
 )
 
+var h = func(w http.ResponseWriter, r *http.Request) {
+	_ = json.NewEncoder(w).Encode(testData{Path: r.RequestURI})
+}
+
 type testKey struct{}
 
 type testData struct {
@@ -38,15 +42,48 @@ func newHandleFuncWrapper(fn http.HandlerFunc) http.Handler {
 	return &handleFuncWrapper{fn: fn}
 }
 
-func TestServer(t *testing.T) {
-	fn := func(w http.ResponseWriter, r *http.Request) {
-		_ = json.NewEncoder(w).Encode(testData{Path: r.RequestURI})
+func TestServeHTTP(t *testing.T) {
+	ln, err := net.Listen("tcp", ":0")
+	if err != nil {
+		t.Fatal(err)
+	}
+	mux := NewServer(Listener(ln))
+	mux.HandleFunc("/index", h)
+	mux.Route("/errors").GET("/cause", func(ctx Context) error {
+		return errors.BadRequest("xxx", "zzz").
+			WithMetadata(map[string]string{"foo": "bar"}).
+			WithCause(fmt.Errorf("error cause"))
+	})
+	if err = mux.WalkRoute(func(r RouteInfo) error {
+		t.Logf("WalkRoute: %+v", r)
+		return nil
+	}); err != nil {
+		t.Fatal(err)
+	}
+	if e, err := mux.Endpoint(); err != nil || e == nil || strings.HasSuffix(e.Host, ":0") {
+		t.Fatal(e, err)
+	}
+	srv := http.Server{Handler: mux}
+	go func() {
+		if err := srv.Serve(ln); err != nil {
+			if errors.Is(err, http.ErrServerClosed) {
+				return
+			}
+			panic(err)
+		}
+	}()
+	time.Sleep(time.Second)
+	if err := srv.Shutdown(context.Background()); err != nil {
+		t.Log(err)
 	}
+}
+
+func TestServer(t *testing.T) {
 	ctx := context.Background()
 	srv := NewServer()
-	srv.Handle("/index", newHandleFuncWrapper(fn))
-	srv.HandleFunc("/index/{id:[0-9]+}", fn)
-	srv.HandlePrefix("/test/prefix", newHandleFuncWrapper(fn))
+	srv.Handle("/index", newHandleFuncWrapper(h))
+	srv.HandleFunc("/index/{id:[0-9]+}", h)
+	srv.HandlePrefix("/test/prefix", newHandleFuncWrapper(h))
 	srv.HandleHeader("content-type", "application/grpc-web+json", func(w http.ResponseWriter, r *http.Request) {
 		_ = json.NewEncoder(w).Encode(testData{Path: r.RequestURI})
 	})
@@ -333,10 +370,16 @@ func TestStrictSlash(t *testing.T) {
 }
 
 func TestListener(t *testing.T) {
-	lis := &net.TCPListener{}
+	lis, err := net.Listen("tcp", ":0")
+	if err != nil {
+		t.Fatal(err)
+	}
 	s := &Server{}
 	Listener(lis)(s)
 	if !reflect.DeepEqual(s.lis, lis) {
 		t.Errorf("expected %v got %v", lis, s.lis)
 	}
+	if e, err := s.Endpoint(); err != nil || e == nil {
+		t.Errorf("expected not empty")
+	}
 }