update micro, add Health/Live/Ready checks
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
		| @@ -13,15 +13,30 @@ type Handler struct { | ||||
| 	opts Options | ||||
| } | ||||
|  | ||||
| type CheckFunc func(context.Context) error | ||||
| type ( | ||||
| 	CheckFunc func(context.Context) error | ||||
| 	Option    func(*Options) | ||||
| ) | ||||
|  | ||||
| type Option func(*Options) | ||||
| type Stater interface { | ||||
| 	Live() bool | ||||
| 	Ready() bool | ||||
| 	Health() bool | ||||
| } | ||||
|  | ||||
| type Options struct { | ||||
| 	Version     string | ||||
| 	Name        string | ||||
| 	LiveChecks  []CheckFunc | ||||
| 	ReadyChecks []CheckFunc | ||||
| 	Version      string | ||||
| 	Name         string | ||||
| 	Staters      []Stater | ||||
| 	LiveChecks   []CheckFunc | ||||
| 	ReadyChecks  []CheckFunc | ||||
| 	HealthChecks []CheckFunc | ||||
| } | ||||
|  | ||||
| func Service(s ...Stater) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Staters = append(o.Staters, s...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func LiveChecks(fns ...CheckFunc) Option { | ||||
| @@ -36,6 +51,12 @@ func ReadyChecks(fns ...CheckFunc) Option { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func HealthChecks(fns ...CheckFunc) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.HealthChecks = append(o.HealthChecks, fns...) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func Name(name string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Name = name | ||||
| @@ -56,18 +77,51 @@ func NewHandler(opts ...Option) *Handler { | ||||
| 	return &Handler{opts: options} | ||||
| } | ||||
|  | ||||
| func (h *Handler) Healthy(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error { | ||||
| 	var err error | ||||
|  | ||||
| 	for _, s := range h.opts.Staters { | ||||
| 		if !s.Health() { | ||||
| 			return errors.ServiceUnavailable(h.opts.Name, "%v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for _, fn := range h.opts.HealthChecks { | ||||
| 		if err = fn(ctx); err != nil { | ||||
| 			return errors.ServiceUnavailable(h.opts.Name, "%v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Handler) Live(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error { | ||||
| 	var err error | ||||
|  | ||||
| 	for _, s := range h.opts.Staters { | ||||
| 		if !s.Live() { | ||||
| 			return errors.ServiceUnavailable(h.opts.Name, "%v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for _, fn := range h.opts.LiveChecks { | ||||
| 		if err = fn(ctx); err != nil { | ||||
| 			return errors.ServiceUnavailable(h.opts.Name, "%v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (h *Handler) Ready(ctx context.Context, req *codecpb.Frame, rsp *codecpb.Frame) error { | ||||
| 	var err error | ||||
|  | ||||
| 	for _, s := range h.opts.Staters { | ||||
| 		if !s.Ready() { | ||||
| 			return errors.ServiceUnavailable(h.opts.Name, "%v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for _, fn := range h.opts.ReadyChecks { | ||||
| 		if err = fn(ctx); err != nil { | ||||
| 			return errors.ServiceUnavailable(h.opts.Name, "%v", err) | ||||
|   | ||||
| @@ -8,6 +8,22 @@ import "openapiv3/annotations.proto"; | ||||
| import "codec/frame.proto"; | ||||
|  | ||||
| service HealthService { | ||||
|   rpc Healthy(micro.codec.Frame) returns (micro.codec.Frame) { | ||||
| 		option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "Healthy"; | ||||
|       responses: { | ||||
|         default: { | ||||
|           reference: { | ||||
|             _ref: "micro.codec.Frame"; | ||||
|           }; | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
| 		option (micro.api.http) = {  | ||||
|       get: "/health"; | ||||
|       additional_bindings: { get: "/healthz"; } | ||||
|     }; | ||||
|   }; | ||||
| 	rpc Live(micro.codec.Frame) returns (micro.codec.Frame) { | ||||
| 		option (micro.openapiv3.openapiv3_operation) = { | ||||
|       operation_id: "Live"; | ||||
| @@ -19,7 +35,10 @@ service HealthService { | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
| 		option (micro.api.http) = { get: "/live"; }; | ||||
| 		option (micro.api.http) = {  | ||||
|       get: "/live"; | ||||
|       additional_bindings: { get: "/livez"; } | ||||
|     }; | ||||
|   }; | ||||
| 	rpc Ready(micro.codec.Frame) returns (micro.codec.Frame) { | ||||
| 		option (micro.openapiv3.openapiv3_operation) = { | ||||
| @@ -32,7 +51,9 @@ service HealthService { | ||||
|         }; | ||||
|       }; | ||||
|     }; | ||||
| 		option (micro.api.http) = { get: "/ready"; }; | ||||
| 		option (micro.api.http) = { get: "/ready"; | ||||
|       additional_bindings: { get: "/readyz"; } | ||||
|     }; | ||||
|   }; | ||||
| 	rpc Version(micro.codec.Frame) returns (micro.codec.Frame) { | ||||
| 		option (micro.openapiv3.openapiv3_operation) = { | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // versions: | ||||
| // - protoc-gen-go-micro v3.10.4 | ||||
| // - protoc              v5.26.1 | ||||
| // - protoc              v5.28.3 | ||||
| // source: health/health.proto | ||||
|  | ||||
| package health_handler | ||||
| @@ -17,12 +17,14 @@ var ( | ||||
| ) | ||||
|  | ||||
| type HealthServiceClient interface { | ||||
| 	Healthy(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) | ||||
| 	Live(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) | ||||
| 	Ready(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) | ||||
| 	Version(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) | ||||
| } | ||||
|  | ||||
| type HealthServiceServer interface { | ||||
| 	Healthy(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
| 	Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
| 	Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
| 	Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
|   | ||||
| @@ -16,6 +16,20 @@ import ( | ||||
|  | ||||
| var ( | ||||
| 	HealthServiceServerEndpoints = []v3.EndpointMetadata{ | ||||
| 		{ | ||||
| 			Name:   "HealthService.Healthy", | ||||
| 			Path:   "/health", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "HealthService.Healthy", | ||||
| 			Path:   "/healthz", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "HealthService.Live", | ||||
| 			Path:   "/live", | ||||
| @@ -23,6 +37,13 @@ var ( | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "HealthService.Live", | ||||
| 			Path:   "/livez", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "HealthService.Ready", | ||||
| 			Path:   "/ready", | ||||
| @@ -30,6 +51,13 @@ var ( | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "HealthService.Ready", | ||||
| 			Path:   "/readyz", | ||||
| 			Method: "GET", | ||||
| 			Body:   "", | ||||
| 			Stream: false, | ||||
| 		}, | ||||
| 		{ | ||||
| 			Name:   "HealthService.Version", | ||||
| 			Path:   "/version", | ||||
| @@ -49,6 +77,24 @@ func NewHealthServiceClient(name string, c client.Client) HealthServiceClient { | ||||
| 	return &healthServiceClient{c: c, name: name} | ||||
| } | ||||
|  | ||||
| func (c *healthServiceClient) Healthy(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| 	opts = append(opts, | ||||
| 		v31.ErrorMap(errmap), | ||||
| 	) | ||||
| 	opts = append(opts, | ||||
| 		v31.Method(http.MethodGet), | ||||
| 		v31.Path("/health"), | ||||
| 	) | ||||
| 	rsp := &codec.Frame{} | ||||
| 	err := c.c.Call(ctx, c.c.NewRequest(c.name, "HealthService.Healthy", req), rsp, opts...) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return rsp, nil | ||||
| } | ||||
|  | ||||
| func (c *healthServiceClient) Live(ctx context.Context, req *codec.Frame, opts ...client.CallOption) (*codec.Frame, error) { | ||||
| 	errmap := make(map[string]interface{}, 1) | ||||
| 	errmap["default"] = &codec.Frame{} | ||||
| @@ -107,6 +153,10 @@ type healthServiceServer struct { | ||||
| 	HealthServiceServer | ||||
| } | ||||
|  | ||||
| func (h *healthServiceServer) Healthy(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error { | ||||
| 	return h.HealthServiceServer.Healthy(ctx, req, rsp) | ||||
| } | ||||
|  | ||||
| func (h *healthServiceServer) Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error { | ||||
| 	return h.HealthServiceServer.Live(ctx, req, rsp) | ||||
| } | ||||
| @@ -121,6 +171,7 @@ func (h *healthServiceServer) Version(ctx context.Context, req *codec.Frame, rsp | ||||
|  | ||||
| func RegisterHealthServiceServer(s server.Server, sh HealthServiceServer, opts ...server.HandlerOption) error { | ||||
| 	type healthService interface { | ||||
| 		Healthy(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
| 		Live(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
| 		Ready(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
| 		Version(ctx context.Context, req *codec.Frame, rsp *codec.Frame) error | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| // Code generated by protoc-gen-go-micro. DO NOT EDIT. | ||||
| // versions: | ||||
| // - protoc-gen-go-micro v3.10.4 | ||||
| // - protoc              v5.26.1 | ||||
| // - protoc              v5.28.3 | ||||
| // source: meter/meter.proto | ||||
|  | ||||
| package meter_handler | ||||
|   | ||||
		Reference in New Issue
	
	Block a user