update micro, add Health/Live/Ready checks
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
		
							
								
								
									
										18
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								go.mod
									
									
									
									
									
								
							| @@ -1,23 +1,23 @@ | ||||
| module go.unistack.org/micro-server-http/v3 | ||||
|  | ||||
| go 1.22 | ||||
| go 1.22.7 | ||||
|  | ||||
| toolchain go1.23.1 | ||||
| toolchain go1.23.3 | ||||
|  | ||||
| require ( | ||||
| 	go.unistack.org/micro-client-http/v3 v3.9.13 | ||||
| 	go.unistack.org/micro-client-http/v3 v3.9.14 | ||||
| 	go.unistack.org/micro-codec-yaml/v3 v3.10.2 | ||||
| 	go.unistack.org/micro-proto/v3 v3.4.1 | ||||
| 	go.unistack.org/micro/v3 v3.10.97 | ||||
| 	golang.org/x/net v0.30.0 | ||||
| 	go.unistack.org/micro/v3 v3.10.108 | ||||
| 	golang.org/x/net v0.31.0 | ||||
| ) | ||||
|  | ||||
| require ( | ||||
| 	github.com/google/gnostic v0.7.0 // indirect | ||||
| 	github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect | ||||
| 	golang.org/x/sys v0.26.0 // indirect | ||||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect | ||||
| 	google.golang.org/grpc v1.67.1 // indirect | ||||
| 	google.golang.org/protobuf v1.35.1 // indirect | ||||
| 	golang.org/x/sys v0.27.0 // indirect | ||||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect | ||||
| 	google.golang.org/grpc v1.68.0 // indirect | ||||
| 	google.golang.org/protobuf v1.35.2 // indirect | ||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||
| ) | ||||
|   | ||||
							
								
								
									
										14
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.sum
									
									
									
									
									
								
							| @@ -876,6 +876,8 @@ go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI | ||||
| go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.13 h1:KUWkDfA7p+dZEIgSsWuPjfj6yeX8rrnHYwrEjdAZvmU= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.13/go.mod h1:WmrmeWWKohGn5ODrCr53wUp4pe/ZE6UYdXh7ECgpOH4= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.14 h1:26BiMcUlGpxpN+S84tpAeMetbd9rbBd+IILq1CkFP2U= | ||||
| go.unistack.org/micro-client-http/v3 v3.9.14/go.mod h1:KS6qxpxGDQmcszBaJpidc1KOr528QflEKoGopl0qYJ8= | ||||
| go.unistack.org/micro-codec-yaml/v3 v3.10.2 h1:02I9XzhaBHqZU8Vd5e2zhf8j4foJ4muPT/x4gdR6E4c= | ||||
| go.unistack.org/micro-codec-yaml/v3 v3.10.2/go.mod h1:A/tYj7x9CRhuin7WxeIvnuo8bMDrZYcJkogVYN8X7rU= | ||||
| go.unistack.org/micro-proto/v3 v3.4.1 h1:UTjLSRz2YZuaHk9iSlVqqsA50JQNAEK2ZFboGqtEa9Q= | ||||
| @@ -883,6 +885,8 @@ go.unistack.org/micro-proto/v3 v3.4.1/go.mod h1:okx/cnOhzuCX0ggl/vToatbCupi0O44d | ||||
| go.unistack.org/micro/v3 v3.10.94/go.mod h1:erMgt3Bl7vQQ0e9UpQyR5NlLiZ9pKeEJ9+1tfYFaqUg= | ||||
| go.unistack.org/micro/v3 v3.10.97 h1:8l7fv+i06/PjPrBBhRC/ZQkWGIOuHPg3jJN0vktYE78= | ||||
| go.unistack.org/micro/v3 v3.10.97/go.mod h1:YzMldzHN9Ei+zy5t/Psu7RUWDZwUfrNYiStSQtTz90g= | ||||
| go.unistack.org/micro/v3 v3.10.108 h1:3L7SkilMVLtH8y3pQIPtr3jjQYrf0AMv1oAkoL3nFkE= | ||||
| go.unistack.org/micro/v3 v3.10.108/go.mod h1:YzMldzHN9Ei+zy5t/Psu7RUWDZwUfrNYiStSQtTz90g= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| @@ -1012,6 +1016,8 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= | ||||
| golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= | ||||
| golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= | ||||
| golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= | ||||
| golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= | ||||
| golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
| golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| @@ -1139,6 +1145,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||||
| golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= | ||||
| golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||||
| golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= | ||||
| golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||
| golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= | ||||
| @@ -1456,6 +1464,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go. | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= | ||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||
| google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= | ||||
| google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||
| @@ -1499,6 +1509,8 @@ google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3 | ||||
| google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= | ||||
| google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= | ||||
| google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= | ||||
| google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= | ||||
| google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= | ||||
| google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= | ||||
| google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= | ||||
| google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= | ||||
| @@ -1521,6 +1533,8 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw | ||||
| google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= | ||||
| google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= | ||||
| google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= | ||||
| google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= | ||||
| google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
|   | ||||
| @@ -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 | ||||
| 	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 | ||||
|   | ||||
							
								
								
									
										33
									
								
								http.go
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								http.go
									
									
									
									
									
								
							| @@ -12,6 +12,7 @@ import ( | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
|  | ||||
| 	"go.unistack.org/micro/v3/broker" | ||||
| @@ -34,6 +35,9 @@ type Server struct { | ||||
| 	errorHandler func(context.Context, server.Handler, http.ResponseWriter, *http.Request, error, int) | ||||
| 	pathHandlers *rhttp.Trie | ||||
| 	opts         server.Options | ||||
| 	stateLive    *atomic.Uint32 | ||||
| 	stateReady   *atomic.Uint32 | ||||
| 	stateHealth  *atomic.Uint32 | ||||
| 	registerRPC  bool | ||||
| 	sync.RWMutex | ||||
| 	registered bool | ||||
| @@ -117,10 +121,7 @@ func (h *Server) Init(opts ...server.Option) error { | ||||
| 		h.RUnlock() | ||||
| 		return err | ||||
| 	} | ||||
| 	if err := h.opts.Transport.Init(); err != nil { | ||||
| 		h.RUnlock() | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	h.RUnlock() | ||||
|  | ||||
| 	h.Lock() | ||||
| @@ -592,9 +593,12 @@ func (h *Server) Start() error { | ||||
| 	} | ||||
|  | ||||
| 	go func() { | ||||
| 		if cerr := hs.Serve(ts); cerr != nil && !errors.Is(cerr, net.ErrClosed) { | ||||
| 		if cerr := hs.Serve(ts); cerr != nil && !errors.Is(cerr, http.ErrServerClosed) { | ||||
| 			h.opts.Logger.Error(h.opts.Context, "serve error", cerr) | ||||
| 		} | ||||
| 		h.stateLive.Store(0) | ||||
| 		h.stateReady.Store(0) | ||||
| 		h.stateHealth.Store(0) | ||||
| 	}() | ||||
|  | ||||
| 	go func() { | ||||
| @@ -670,6 +674,10 @@ func (h *Server) Start() error { | ||||
| 		ch <- err | ||||
| 	}() | ||||
|  | ||||
| 	h.stateLive.Store(1) | ||||
| 	h.stateReady.Store(1) | ||||
| 	h.stateHealth.Store(1) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -687,6 +695,18 @@ func (h *Server) Name() string { | ||||
| 	return h.opts.Name | ||||
| } | ||||
|  | ||||
| func (h *Server) Live() bool { | ||||
| 	return h.stateLive.Load() == 1 | ||||
| } | ||||
|  | ||||
| func (h *Server) Ready() bool { | ||||
| 	return h.stateReady.Load() == 1 | ||||
| } | ||||
|  | ||||
| func (h *Server) Health() bool { | ||||
| 	return h.stateHealth.Load() == 1 | ||||
| } | ||||
|  | ||||
| func NewServer(opts ...server.Option) *Server { | ||||
| 	options := server.NewOptions(opts...) | ||||
| 	eh := DefaultErrorHandler | ||||
| @@ -694,6 +714,9 @@ func NewServer(opts ...server.Option) *Server { | ||||
| 		eh = v | ||||
| 	} | ||||
| 	return &Server{ | ||||
| 		stateLive:    &atomic.Uint32{}, | ||||
| 		stateReady:   &atomic.Uint32{}, | ||||
| 		stateHealth:  &atomic.Uint32{}, | ||||
| 		opts:         options, | ||||
| 		exit:         make(chan chan error), | ||||
| 		subscribers:  make(map[*httpSubscriber][]broker.Subscriber), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user