diff --git a/README.md b/README.md index 3ee139f..b6f6004 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,32 @@ The result of the above command is: } ``` +## Health check + +You can check the health status of the node. + +```bash +$ ./bin/cete healthcheck | jq . +``` + +Also provides the following REST APIs + +### Liveness prove + +This endpoint always returns 200 and should be used to check Cete health. + +```bash +$ curl -X GET http://localhost:8000/v1/liveness_check | jq . +``` + +### Readiness probe + +This endpoint returns 200 when Cete is ready to serve traffic (i.e. respond to queries). + +```bash +$ curl -X GET http://localhost:8000/v1/readiness_check | jq . +``` + ## Putting a key-value To put a key-value, execute the following command: diff --git a/client/grpc_client.go b/client/grpc_client.go index 39d271f..257cca5 100644 --- a/client/grpc_client.go +++ b/client/grpc_client.go @@ -87,6 +87,22 @@ func (c *GRPCClient) Target() string { return c.conn.Target() } +func (c *GRPCClient) LivenessCheck(opts ...grpc.CallOption) (*protobuf.LivenessCheckResponse, error) { + if resp, err := c.client.LivenessCheck(c.ctx, &empty.Empty{}, opts...); err != nil { + return nil, err + } else { + return resp, nil + } +} + +func (c *GRPCClient) ReadinessCheck(opts ...grpc.CallOption) (*protobuf.ReadinessCheckResponse, error) { + if resp, err := c.client.ReadinessCheck(c.ctx, &empty.Empty{}, opts...); err != nil { + return nil, err + } else { + return resp, nil + } +} + func (c *GRPCClient) Join(req *protobuf.JoinRequest, opts ...grpc.CallOption) error { if _, err := c.client.Join(c.ctx, req, opts...); err != nil { return err diff --git a/cmd/healthcheck.go b/cmd/healthcheck.go new file mode 100644 index 0000000..89b1352 --- /dev/null +++ b/cmd/healthcheck.go @@ -0,0 +1,102 @@ +package cmd + +import ( + "context" + "encoding/json" + "fmt" + "os" + + "github.com/mitchellh/go-homedir" + "github.com/mosuka/cete/client" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ( + healthCheckCmd = &cobra.Command{ + Use: "healthcheck", + Short: "Health check a node", + Long: "Health check a node", + RunE: func(cmd *cobra.Command, args []string) error { + grpcAddress = viper.GetString("grpc_address") + + certificateFile = viper.GetString("certificate_file") + commonName = viper.GetString("common_name") + + c, err := client.NewGRPCClientWithContextTLS(grpcAddress, context.Background(), certificateFile, commonName) + if err != nil { + return err + } + defer func() { + _ = c.Close() + }() + + lResp, err := c.LivenessCheck() + if err != nil { + return err + } + + rResp, err := c.ReadinessCheck() + if err != nil { + return err + } + + resp := map[string]bool{ + "liveness": lResp.Alive, + "readiness:": rResp.Ready, + } + + respBytes, err := json.Marshal(resp) + if err != nil { + return err + } + + fmt.Println(string(respBytes)) + + return nil + }, + } +) + +func init() { + rootCmd.AddCommand(healthCheckCmd) + + cobra.OnInitialize(func() { + if configFile != "" { + viper.SetConfigFile(configFile) + } else { + home, err := homedir.Dir() + if err != nil { + _, _ = fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + viper.AddConfigPath("/etc") + viper.AddConfigPath(home) + viper.SetConfigName("cete") + + } + + viper.SetEnvPrefix("CETE") + viper.AutomaticEnv() + + if err := viper.ReadInConfig(); err != nil { + switch err.(type) { + case viper.ConfigFileNotFoundError: + // cete.yaml does not found in config search path + default: + _, _ = fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + } + }) + + healthCheckCmd.PersistentFlags().StringVar(&configFile, "config-file", "", "config file. if omitted, cete.yaml in /etc and home directory will be searched") + healthCheckCmd.PersistentFlags().StringVar(&grpcAddress, "grpc-address", ":9000", "gRPC server listen address") + healthCheckCmd.PersistentFlags().StringVar(&certificateFile, "certificate-file", "", "path to the client server TLS certificate file") + healthCheckCmd.PersistentFlags().StringVar(&commonName, "common-name", "", "certificate common name") + + _ = viper.BindPFlag("grpc_address", healthCheckCmd.PersistentFlags().Lookup("grpc-address")) + _ = viper.BindPFlag("certificate_file", healthCheckCmd.PersistentFlags().Lookup("certificate-file")) + _ = viper.BindPFlag("common_name", healthCheckCmd.PersistentFlags().Lookup("common-name")) +} diff --git a/errors/errors.go b/errors/errors.go index 41e1fab..c8f5d2f 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package errors import "errors" @@ -19,6 +5,7 @@ import "errors" var ( ErrNotFoundLeader = errors.New("does not found leader") ErrNodeAlreadyExists = errors.New("node already exists") + ErrNodeNotReady = errors.New("node not ready") ErrNotFound = errors.New("not found") ErrTimeout = errors.New("timeout") ) diff --git a/marshaler/marshaler.go b/marshaler/marshaler.go index c5e51f5..a9891f6 100644 --- a/marshaler/marshaler.go +++ b/marshaler/marshaler.go @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package marshaler import ( diff --git a/marshaler/util.go b/marshaler/util.go index 085f6c6..342e646 100644 --- a/marshaler/util.go +++ b/marshaler/util.go @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package marshaler import ( @@ -24,16 +10,25 @@ import ( ) func init() { + registry.RegisterType("protobuf.LivenessCheckResponse", reflect.TypeOf(protobuf.LivenessCheckResponse{})) + registry.RegisterType("protobuf.ReadinessCheckResponse", reflect.TypeOf(protobuf.ReadinessCheckResponse{})) + registry.RegisterType("protobuf.Metadata", reflect.TypeOf(protobuf.Metadata{})) + registry.RegisterType("protobuf.Node", reflect.TypeOf(protobuf.Node{})) + registry.RegisterType("protobuf.Cluster", reflect.TypeOf(protobuf.Cluster{})) registry.RegisterType("protobuf.JoinRequest", reflect.TypeOf(protobuf.JoinRequest{})) registry.RegisterType("protobuf.LeaveRequest", reflect.TypeOf(protobuf.LeaveRequest{})) + registry.RegisterType("protobuf.NodeResponse", reflect.TypeOf(protobuf.NodeResponse{})) + registry.RegisterType("protobuf.ClusterResponse", reflect.TypeOf(protobuf.ClusterResponse{})) registry.RegisterType("protobuf.GetRequest", reflect.TypeOf(protobuf.GetRequest{})) + registry.RegisterType("protobuf.GetResponse", reflect.TypeOf(protobuf.GetResponse{})) registry.RegisterType("protobuf.SetRequest", reflect.TypeOf(protobuf.SetRequest{})) registry.RegisterType("protobuf.DeleteRequest", reflect.TypeOf(protobuf.DeleteRequest{})) - registry.RegisterType("protobuf.KeyValuePair", reflect.TypeOf(protobuf.KeyValuePair{})) registry.RegisterType("protobuf.SetMetadataRequest", reflect.TypeOf(protobuf.SetMetadataRequest{})) registry.RegisterType("protobuf.DeleteMetadataRequest", reflect.TypeOf(protobuf.DeleteMetadataRequest{})) - registry.RegisterType("protobuf.Metadata", reflect.TypeOf(protobuf.Metadata{})) - registry.RegisterType("protobuf.Node", reflect.TypeOf(protobuf.Node{})) + registry.RegisterType("protobuf.Event", reflect.TypeOf(protobuf.Event{})) + registry.RegisterType("protobuf.WatchResponse", reflect.TypeOf(protobuf.WatchResponse{})) + registry.RegisterType("protobuf.MetricsResponse", reflect.TypeOf(protobuf.MetricsResponse{})) + registry.RegisterType("protobuf.KeyValuePair", reflect.TypeOf(protobuf.KeyValuePair{})) registry.RegisterType("map[string]interface {}", reflect.TypeOf((map[string]interface{})(nil))) } diff --git a/protobuf/kvs.pb.go b/protobuf/kvs.pb.go index 354050e..a7a8ecb 100644 --- a/protobuf/kvs.pb.go +++ b/protobuf/kvs.pb.go @@ -59,7 +59,85 @@ func (x Event_Type) String() string { } func (Event_Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{13, 0} + return fileDescriptor_431078ad7b21f851, []int{15, 0} +} + +type LivenessCheckResponse struct { + Alive bool `protobuf:"varint,1,opt,name=alive,proto3" json:"alive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LivenessCheckResponse) Reset() { *m = LivenessCheckResponse{} } +func (m *LivenessCheckResponse) String() string { return proto.CompactTextString(m) } +func (*LivenessCheckResponse) ProtoMessage() {} +func (*LivenessCheckResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_431078ad7b21f851, []int{0} +} + +func (m *LivenessCheckResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_LivenessCheckResponse.Unmarshal(m, b) +} +func (m *LivenessCheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_LivenessCheckResponse.Marshal(b, m, deterministic) +} +func (m *LivenessCheckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LivenessCheckResponse.Merge(m, src) +} +func (m *LivenessCheckResponse) XXX_Size() int { + return xxx_messageInfo_LivenessCheckResponse.Size(m) +} +func (m *LivenessCheckResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LivenessCheckResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LivenessCheckResponse proto.InternalMessageInfo + +func (m *LivenessCheckResponse) GetAlive() bool { + if m != nil { + return m.Alive + } + return false +} + +type ReadinessCheckResponse struct { + Ready bool `protobuf:"varint,1,opt,name=ready,proto3" json:"ready,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ReadinessCheckResponse) Reset() { *m = ReadinessCheckResponse{} } +func (m *ReadinessCheckResponse) String() string { return proto.CompactTextString(m) } +func (*ReadinessCheckResponse) ProtoMessage() {} +func (*ReadinessCheckResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_431078ad7b21f851, []int{1} +} + +func (m *ReadinessCheckResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ReadinessCheckResponse.Unmarshal(m, b) +} +func (m *ReadinessCheckResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ReadinessCheckResponse.Marshal(b, m, deterministic) +} +func (m *ReadinessCheckResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ReadinessCheckResponse.Merge(m, src) +} +func (m *ReadinessCheckResponse) XXX_Size() int { + return xxx_messageInfo_ReadinessCheckResponse.Size(m) +} +func (m *ReadinessCheckResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ReadinessCheckResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ReadinessCheckResponse proto.InternalMessageInfo + +func (m *ReadinessCheckResponse) GetReady() bool { + if m != nil { + return m.Ready + } + return false } type Metadata struct { @@ -74,7 +152,7 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{0} + return fileDescriptor_431078ad7b21f851, []int{2} } func (m *Metadata) XXX_Unmarshal(b []byte) error { @@ -122,7 +200,7 @@ func (m *Node) Reset() { *m = Node{} } func (m *Node) String() string { return proto.CompactTextString(m) } func (*Node) ProtoMessage() {} func (*Node) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{1} + return fileDescriptor_431078ad7b21f851, []int{3} } func (m *Node) XXX_Unmarshal(b []byte) error { @@ -176,7 +254,7 @@ func (m *Cluster) Reset() { *m = Cluster{} } func (m *Cluster) String() string { return proto.CompactTextString(m) } func (*Cluster) ProtoMessage() {} func (*Cluster) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{2} + return fileDescriptor_431078ad7b21f851, []int{4} } func (m *Cluster) XXX_Unmarshal(b []byte) error { @@ -223,7 +301,7 @@ func (m *JoinRequest) Reset() { *m = JoinRequest{} } func (m *JoinRequest) String() string { return proto.CompactTextString(m) } func (*JoinRequest) ProtoMessage() {} func (*JoinRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{3} + return fileDescriptor_431078ad7b21f851, []int{5} } func (m *JoinRequest) XXX_Unmarshal(b []byte) error { @@ -269,7 +347,7 @@ func (m *LeaveRequest) Reset() { *m = LeaveRequest{} } func (m *LeaveRequest) String() string { return proto.CompactTextString(m) } func (*LeaveRequest) ProtoMessage() {} func (*LeaveRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{4} + return fileDescriptor_431078ad7b21f851, []int{6} } func (m *LeaveRequest) XXX_Unmarshal(b []byte) error { @@ -308,7 +386,7 @@ func (m *NodeResponse) Reset() { *m = NodeResponse{} } func (m *NodeResponse) String() string { return proto.CompactTextString(m) } func (*NodeResponse) ProtoMessage() {} func (*NodeResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{5} + return fileDescriptor_431078ad7b21f851, []int{7} } func (m *NodeResponse) XXX_Unmarshal(b []byte) error { @@ -347,7 +425,7 @@ func (m *ClusterResponse) Reset() { *m = ClusterResponse{} } func (m *ClusterResponse) String() string { return proto.CompactTextString(m) } func (*ClusterResponse) ProtoMessage() {} func (*ClusterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{6} + return fileDescriptor_431078ad7b21f851, []int{8} } func (m *ClusterResponse) XXX_Unmarshal(b []byte) error { @@ -386,7 +464,7 @@ func (m *GetRequest) Reset() { *m = GetRequest{} } func (m *GetRequest) String() string { return proto.CompactTextString(m) } func (*GetRequest) ProtoMessage() {} func (*GetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{7} + return fileDescriptor_431078ad7b21f851, []int{9} } func (m *GetRequest) XXX_Unmarshal(b []byte) error { @@ -425,7 +503,7 @@ func (m *GetResponse) Reset() { *m = GetResponse{} } func (m *GetResponse) String() string { return proto.CompactTextString(m) } func (*GetResponse) ProtoMessage() {} func (*GetResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{8} + return fileDescriptor_431078ad7b21f851, []int{10} } func (m *GetResponse) XXX_Unmarshal(b []byte) error { @@ -465,7 +543,7 @@ func (m *SetRequest) Reset() { *m = SetRequest{} } func (m *SetRequest) String() string { return proto.CompactTextString(m) } func (*SetRequest) ProtoMessage() {} func (*SetRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{9} + return fileDescriptor_431078ad7b21f851, []int{11} } func (m *SetRequest) XXX_Unmarshal(b []byte) error { @@ -511,7 +589,7 @@ func (m *DeleteRequest) Reset() { *m = DeleteRequest{} } func (m *DeleteRequest) String() string { return proto.CompactTextString(m) } func (*DeleteRequest) ProtoMessage() {} func (*DeleteRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{10} + return fileDescriptor_431078ad7b21f851, []int{12} } func (m *DeleteRequest) XXX_Unmarshal(b []byte) error { @@ -551,7 +629,7 @@ func (m *SetMetadataRequest) Reset() { *m = SetMetadataRequest{} } func (m *SetMetadataRequest) String() string { return proto.CompactTextString(m) } func (*SetMetadataRequest) ProtoMessage() {} func (*SetMetadataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{11} + return fileDescriptor_431078ad7b21f851, []int{13} } func (m *SetMetadataRequest) XXX_Unmarshal(b []byte) error { @@ -597,7 +675,7 @@ func (m *DeleteMetadataRequest) Reset() { *m = DeleteMetadataRequest{} } func (m *DeleteMetadataRequest) String() string { return proto.CompactTextString(m) } func (*DeleteMetadataRequest) ProtoMessage() {} func (*DeleteMetadataRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{12} + return fileDescriptor_431078ad7b21f851, []int{14} } func (m *DeleteMetadataRequest) XXX_Unmarshal(b []byte) error { @@ -637,7 +715,7 @@ func (m *Event) Reset() { *m = Event{} } func (m *Event) String() string { return proto.CompactTextString(m) } func (*Event) ProtoMessage() {} func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{13} + return fileDescriptor_431078ad7b21f851, []int{15} } func (m *Event) XXX_Unmarshal(b []byte) error { @@ -683,7 +761,7 @@ func (m *WatchResponse) Reset() { *m = WatchResponse{} } func (m *WatchResponse) String() string { return proto.CompactTextString(m) } func (*WatchResponse) ProtoMessage() {} func (*WatchResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{14} + return fileDescriptor_431078ad7b21f851, []int{16} } func (m *WatchResponse) XXX_Unmarshal(b []byte) error { @@ -722,7 +800,7 @@ func (m *MetricsResponse) Reset() { *m = MetricsResponse{} } func (m *MetricsResponse) String() string { return proto.CompactTextString(m) } func (*MetricsResponse) ProtoMessage() {} func (*MetricsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{15} + return fileDescriptor_431078ad7b21f851, []int{17} } func (m *MetricsResponse) XXX_Unmarshal(b []byte) error { @@ -762,7 +840,7 @@ func (m *KeyValuePair) Reset() { *m = KeyValuePair{} } func (m *KeyValuePair) String() string { return proto.CompactTextString(m) } func (*KeyValuePair) ProtoMessage() {} func (*KeyValuePair) Descriptor() ([]byte, []int) { - return fileDescriptor_431078ad7b21f851, []int{16} + return fileDescriptor_431078ad7b21f851, []int{18} } func (m *KeyValuePair) XXX_Unmarshal(b []byte) error { @@ -799,6 +877,8 @@ func (m *KeyValuePair) GetValue() []byte { func init() { proto.RegisterEnum("kvs.Event_Type", Event_Type_name, Event_Type_value) + proto.RegisterType((*LivenessCheckResponse)(nil), "kvs.LivenessCheckResponse") + proto.RegisterType((*ReadinessCheckResponse)(nil), "kvs.ReadinessCheckResponse") proto.RegisterType((*Metadata)(nil), "kvs.Metadata") proto.RegisterType((*Node)(nil), "kvs.Node") proto.RegisterType((*Cluster)(nil), "kvs.Cluster") @@ -822,61 +902,67 @@ func init() { func init() { proto.RegisterFile("protobuf/kvs.proto", fileDescriptor_431078ad7b21f851) } var fileDescriptor_431078ad7b21f851 = []byte{ - // 861 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xdd, 0x72, 0xdb, 0x54, - 0x10, 0xae, 0xfc, 0x13, 0x3b, 0x6b, 0x27, 0x51, 0xb7, 0x26, 0xb8, 0x6a, 0x49, 0xd3, 0xd3, 0x19, - 0x08, 0x86, 0x58, 0x34, 0x30, 0xfc, 0x64, 0xe8, 0x45, 0x49, 0x33, 0x9d, 0xa1, 0x29, 0xcd, 0xc8, - 0x50, 0x66, 0xb8, 0x61, 0x4e, 0xac, 0xc5, 0xd6, 0xd8, 0x96, 0x84, 0x74, 0xec, 0x8e, 0xa6, 0xd3, - 0x1b, 0x5e, 0x81, 0xe1, 0xc9, 0x78, 0x05, 0x5e, 0x81, 0x7b, 0xe6, 0xfc, 0xc8, 0xb2, 0xeb, 0x8a, - 0xf6, 0xca, 0x3a, 0xfb, 0xed, 0x7e, 0xfb, 0x69, 0xcf, 0xb7, 0x32, 0x60, 0x9c, 0x44, 0x22, 0xba, - 0x9a, 0xff, 0xe6, 0x4e, 0x16, 0x69, 0x5f, 0x1d, 0xb0, 0x3a, 0x59, 0xa4, 0xce, 0xcd, 0x51, 0x14, - 0x8d, 0xa6, 0xe4, 0x2e, 0x71, 0x1e, 0x66, 0x1a, 0x77, 0x6e, 0xbd, 0x0e, 0xd1, 0x2c, 0x16, 0x39, - 0x78, 0xdb, 0x80, 0x3c, 0x0e, 0x5c, 0x1e, 0x86, 0x91, 0xe0, 0x22, 0x88, 0x42, 0x43, 0xed, 0x7c, - 0xaa, 0x7e, 0x86, 0xc7, 0x23, 0x0a, 0x8f, 0xd3, 0x17, 0x7c, 0x34, 0xa2, 0xc4, 0x8d, 0x62, 0x95, - 0xb1, 0x99, 0xcd, 0x1e, 0x41, 0xf3, 0x29, 0x09, 0xee, 0x73, 0xc1, 0xf1, 0x16, 0x6c, 0x8f, 0x92, - 0x78, 0xf8, 0x2b, 0xf7, 0xfd, 0xa4, 0x6b, 0x1d, 0x5a, 0x47, 0xdb, 0x5e, 0x53, 0x06, 0x1e, 0xfa, - 0x7e, 0x22, 0xc1, 0xb1, 0x10, 0xb1, 0x06, 0x2b, 0x1a, 0x94, 0x01, 0x09, 0x32, 0x1f, 0x6a, 0x3f, - 0x44, 0x3e, 0xc9, 0xa4, 0xab, 0x20, 0xf4, 0xd7, 0x18, 0x64, 0x40, 0x31, 0x7c, 0x0c, 0xcd, 0x99, - 0x69, 0xa5, 0x08, 0x5a, 0x27, 0x3b, 0x7d, 0x39, 0x91, 0xbc, 0xbf, 0xb7, 0x84, 0xb1, 0x03, 0xf5, - 0x54, 0x70, 0x41, 0xdd, 0xaa, 0xe2, 0xd0, 0x07, 0xf6, 0x97, 0x05, 0x8d, 0xb3, 0xe9, 0x3c, 0x15, - 0x94, 0xe0, 0x31, 0xd4, 0xc3, 0xc8, 0xa7, 0xb4, 0x6b, 0x1d, 0x56, 0x8f, 0x5a, 0x27, 0xef, 0x2b, - 0x26, 0x03, 0xf6, 0xa5, 0x96, 0xf4, 0x3c, 0x14, 0x49, 0xe6, 0xe9, 0x2c, 0xdc, 0x87, 0xad, 0x29, - 0x71, 0x9f, 0x72, 0xe9, 0xe6, 0xe4, 0x9c, 0x01, 0x14, 0xc9, 0x68, 0x43, 0x75, 0x42, 0x99, 0x11, - 0x2e, 0x1f, 0xf1, 0x0e, 0xd4, 0x17, 0x7c, 0x3a, 0x27, 0x23, 0x78, 0x5b, 0xb5, 0x91, 0x15, 0x9e, - 0x8e, 0x9f, 0x56, 0xbe, 0xb6, 0xd8, 0xb7, 0xd0, 0xfa, 0x3e, 0x0a, 0x42, 0x8f, 0x7e, 0x9f, 0x53, - 0x2a, 0x70, 0x17, 0x2a, 0x81, 0x6f, 0x48, 0x2a, 0x81, 0x8f, 0x1f, 0x40, 0x4d, 0x8a, 0xd8, 0xa4, - 0x50, 0x61, 0x76, 0x00, 0xed, 0x0b, 0xe2, 0x0b, 0x2a, 0x29, 0x67, 0xc7, 0xd0, 0x56, 0xd9, 0x94, - 0xc6, 0x51, 0x98, 0xd2, 0x92, 0xce, 0x7a, 0x33, 0xdd, 0x37, 0xb0, 0x67, 0xc6, 0xb0, 0xac, 0xf8, - 0x10, 0x1a, 0x43, 0x1d, 0x32, 0x45, 0xed, 0xd5, 0x69, 0x79, 0x39, 0xc8, 0x0e, 0x00, 0x1e, 0x93, - 0xc8, 0x75, 0x6c, 0x0c, 0x83, 0xdd, 0x83, 0x96, 0xc2, 0x0d, 0x6d, 0x27, 0x9f, 0x8d, 0x4c, 0x69, - 0x9b, 0x81, 0xb0, 0x2f, 0x00, 0x06, 0xff, 0x43, 0x52, 0x54, 0x55, 0x56, 0xab, 0xee, 0xc2, 0xce, - 0x23, 0x9a, 0x92, 0xa0, 0xf2, 0xee, 0xcf, 0x00, 0x07, 0x24, 0x96, 0x66, 0x29, 0x19, 0xf6, 0xbb, - 0x9b, 0x8c, 0x7d, 0x04, 0xef, 0xe9, 0x9e, 0x6f, 0xe1, 0x94, 0xbe, 0xab, 0x9f, 0x2f, 0x28, 0x14, - 0x78, 0x0f, 0x6a, 0x22, 0x8b, 0xf5, 0x1b, 0xef, 0x9e, 0xec, 0x29, 0x66, 0x85, 0xf4, 0x7f, 0xcc, - 0x62, 0xf2, 0x14, 0x88, 0x47, 0x50, 0x5b, 0x69, 0xdf, 0xe9, 0xeb, 0x6d, 0xed, 0xe7, 0xab, 0xdc, - 0x7f, 0x18, 0x66, 0x9e, 0xca, 0x60, 0x0f, 0xa0, 0x26, 0xeb, 0xb0, 0x05, 0x8d, 0x9f, 0xc2, 0x49, - 0x18, 0xbd, 0x08, 0xed, 0x6b, 0xd8, 0x84, 0x9a, 0x74, 0x93, 0x6d, 0xe1, 0x36, 0xd4, 0x95, 0x33, - 0xec, 0x0a, 0x36, 0xa0, 0x3a, 0x20, 0x61, 0x57, 0x11, 0x60, 0x4b, 0x8b, 0xb6, 0x6b, 0xec, 0x3e, - 0xec, 0xfc, 0xcc, 0xc5, 0x70, 0xbc, 0xbc, 0x91, 0x43, 0xa8, 0x93, 0x54, 0x63, 0xae, 0x19, 0x0a, - 0x7d, 0x9e, 0x06, 0xd8, 0x27, 0xb0, 0xf7, 0x94, 0x44, 0x12, 0x0c, 0xd3, 0x65, 0x51, 0x17, 0x1a, - 0x33, 0x1d, 0x32, 0x17, 0x99, 0x1f, 0xd9, 0x97, 0xd0, 0x7e, 0x42, 0xd9, 0x73, 0x79, 0x41, 0x97, - 0x3c, 0x48, 0xde, 0xf5, 0x32, 0x4f, 0xfe, 0xad, 0x43, 0xf5, 0xc9, 0xf3, 0x01, 0x9e, 0x99, 0xaf, - 0xc2, 0xfe, 0xc6, 0x08, 0xce, 0xe5, 0xd7, 0xcc, 0xb9, 0x5e, 0x78, 0xd7, 0x88, 0x61, 0xf6, 0x1f, - 0x7f, 0xff, 0xf3, 0x67, 0x05, 0xb0, 0xe9, 0x2e, 0xee, 0xbb, 0xd2, 0xcf, 0x78, 0xa9, 0xc7, 0x81, - 0xb6, 0x4a, 0x5e, 0xd9, 0x33, 0xa7, 0x84, 0x96, 0x1d, 0x28, 0x8e, 0xae, 0x63, 0x4b, 0x0e, 0xe3, - 0x6d, 0xf7, 0x65, 0xe0, 0xbf, 0x3a, 0x55, 0x1b, 0x82, 0x17, 0xc5, 0x57, 0xa4, 0x4c, 0x59, 0x67, - 0x6d, 0x41, 0x72, 0x71, 0x37, 0x14, 0xf1, 0x0e, 0xb6, 0x56, 0x88, 0xf1, 0xc2, 0x5c, 0x12, 0xea, - 0xb7, 0x59, 0x5d, 0xe5, 0x52, 0x85, 0x5d, 0x45, 0x84, 0xbd, 0x0d, 0x85, 0x78, 0x09, 0xcd, 0x41, - 0xc8, 0xe3, 0x74, 0x1c, 0x89, 0x52, 0x71, 0x65, 0xac, 0x1d, 0xc5, 0xba, 0x8b, 0x6d, 0xc9, 0x9a, - 0xe6, 0x2c, 0x67, 0x50, 0x7d, 0x4c, 0x02, 0xb5, 0x57, 0x8b, 0xf5, 0x76, 0xec, 0x22, 0x60, 0x5e, - 0xef, 0xa6, 0xaa, 0xbf, 0x81, 0xd7, 0x65, 0xbd, 0xf4, 0xa7, 0xfb, 0x72, 0x42, 0xd9, 0x83, 0x5e, - 0xef, 0x15, 0x5e, 0x28, 0xfb, 0x19, 0x92, 0x62, 0xbd, 0x4b, 0xa5, 0xdc, 0x56, 0x54, 0xfb, 0xce, - 0x26, 0xd5, 0xa9, 0xd5, 0xc3, 0x67, 0xb9, 0x87, 0x11, 0x15, 0xe1, 0xda, 0xe6, 0x97, 0x72, 0x1a, - 0x79, 0xbd, 0x37, 0xc8, 0xfb, 0x0a, 0xea, 0x6a, 0x11, 0x4a, 0x47, 0xa6, 0xfb, 0xac, 0x2d, 0x0b, - 0xbb, 0xf6, 0x99, 0x25, 0xad, 0x60, 0xd6, 0xe1, 0x2d, 0x56, 0x78, 0x6d, 0x69, 0xd6, 0xad, 0x60, - 0xf6, 0xe5, 0xbb, 0xbb, 0xbf, 0xdc, 0x19, 0x05, 0x62, 0x3c, 0xbf, 0xea, 0x0f, 0xa3, 0x99, 0x3b, - 0x8b, 0xd2, 0xf9, 0x84, 0xbb, 0x43, 0x12, 0xc5, 0xdf, 0xf8, 0xd5, 0x96, 0x7a, 0xfa, 0xfc, 0xbf, - 0x00, 0x00, 0x00, 0xff, 0xff, 0x7c, 0x29, 0x2d, 0x7b, 0x14, 0x08, 0x00, 0x00, + // 955 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x96, 0x5d, 0x6e, 0xdb, 0x46, + 0x10, 0xc7, 0xa3, 0x2f, 0x4b, 0x1e, 0xc9, 0x36, 0x33, 0x96, 0x5d, 0x85, 0x4e, 0x1d, 0x67, 0x03, + 0xb4, 0xae, 0x5a, 0x89, 0x8d, 0x5b, 0xf4, 0xc3, 0x68, 0x1e, 0x52, 0xc5, 0x08, 0xd0, 0x28, 0x8d, + 0x41, 0xb5, 0x29, 0xd0, 0x17, 0x63, 0x25, 0x4e, 0x25, 0x42, 0x12, 0xc9, 0x92, 0x2b, 0x05, 0x42, + 0x90, 0x97, 0x5e, 0xa1, 0xe8, 0x65, 0x7a, 0x8d, 0x5e, 0xa1, 0x07, 0x29, 0x76, 0xb9, 0x14, 0xa5, + 0x48, 0x6c, 0xf2, 0x64, 0xed, 0xce, 0xcc, 0x6f, 0xfe, 0x9c, 0x9d, 0x19, 0x18, 0x30, 0x08, 0x7d, + 0xe1, 0xf7, 0x67, 0xbf, 0x59, 0xe3, 0x79, 0xd4, 0x56, 0x07, 0x2c, 0x8c, 0xe7, 0x91, 0x79, 0x67, + 0xe8, 0xfb, 0xc3, 0x09, 0x59, 0x4b, 0x3b, 0xf7, 0x16, 0xb1, 0xdd, 0x3c, 0x79, 0xdb, 0x44, 0xd3, + 0x40, 0x24, 0xc6, 0xbb, 0xda, 0xc8, 0x03, 0xd7, 0xe2, 0x9e, 0xe7, 0x0b, 0x2e, 0x5c, 0xdf, 0xd3, + 0x68, 0xf3, 0x33, 0xf5, 0x67, 0xd0, 0x1a, 0x92, 0xd7, 0x8a, 0x5e, 0xf1, 0xe1, 0x90, 0x42, 0xcb, + 0x0f, 0x94, 0xc7, 0xa6, 0x37, 0x6b, 0xc1, 0x51, 0xd7, 0x9d, 0x93, 0x47, 0x51, 0xd4, 0x19, 0xd1, + 0x60, 0x6c, 0x53, 0x14, 0xf8, 0x5e, 0x44, 0x58, 0x87, 0x12, 0x9f, 0xb8, 0x73, 0x6a, 0xe4, 0xce, + 0x72, 0xe7, 0x15, 0x3b, 0x3e, 0xb0, 0x36, 0x1c, 0xdb, 0xc4, 0x1d, 0x77, 0xab, 0x7f, 0x48, 0xdc, + 0x59, 0x24, 0xfe, 0xea, 0xc0, 0x9e, 0x40, 0xe5, 0x39, 0x09, 0xee, 0x70, 0xc1, 0xf1, 0x04, 0x76, + 0x87, 0x61, 0x30, 0xb8, 0xe1, 0x8e, 0x13, 0x2a, 0xaf, 0x5d, 0xbb, 0x22, 0x2f, 0x1e, 0x3b, 0x4e, + 0x28, 0x8d, 0x23, 0x21, 0x82, 0xd8, 0x98, 0x8f, 0x8d, 0xf2, 0x42, 0x1a, 0x99, 0x03, 0xc5, 0x1f, + 0x7d, 0x87, 0xa4, 0x53, 0xdf, 0xf5, 0x9c, 0x35, 0x82, 0xbc, 0x50, 0x84, 0x4f, 0xa0, 0x32, 0xd5, + 0xa9, 0x14, 0xa0, 0x7a, 0xb1, 0xd7, 0x96, 0x05, 0x4f, 0xf2, 0xdb, 0x4b, 0xb3, 0xd4, 0x1a, 0x09, + 0x2e, 0xa8, 0x51, 0x50, 0x8c, 0xf8, 0xc0, 0xfe, 0xca, 0x41, 0xb9, 0x33, 0x99, 0x45, 0x82, 0x42, + 0x6c, 0x41, 0xc9, 0xf3, 0x1d, 0x8a, 0x1a, 0xb9, 0xb3, 0xc2, 0x79, 0xf5, 0xe2, 0x03, 0x45, 0xd2, + 0xc6, 0xb6, 0xd4, 0x12, 0x5d, 0x79, 0x22, 0x5c, 0xd8, 0xb1, 0x17, 0x1e, 0xc3, 0xce, 0x84, 0xb8, + 0x43, 0x89, 0x74, 0x7d, 0x32, 0x3b, 0x00, 0xa9, 0x33, 0x1a, 0x50, 0x18, 0xd3, 0x42, 0x0b, 0x97, + 0x3f, 0xf1, 0x1e, 0x94, 0xe6, 0x7c, 0x32, 0x23, 0x2d, 0x78, 0x57, 0xa5, 0x91, 0x11, 0x76, 0x7c, + 0x7f, 0x99, 0xff, 0x26, 0xc7, 0xbe, 0x83, 0xea, 0x0f, 0xbe, 0xeb, 0xd9, 0xf4, 0xfb, 0x8c, 0x22, + 0x81, 0xfb, 0x90, 0x77, 0x1d, 0x0d, 0xc9, 0xbb, 0x0e, 0x7e, 0x08, 0x45, 0x29, 0x62, 0x13, 0xa1, + 0xae, 0xd9, 0x29, 0xd4, 0xba, 0xc4, 0xe7, 0x94, 0x11, 0xce, 0x5a, 0x50, 0x53, 0xde, 0xc9, 0x3b, + 0x26, 0xb8, 0xdc, 0x76, 0xdc, 0xb7, 0x70, 0xa0, 0xcb, 0xb0, 0x8c, 0xf8, 0x08, 0xca, 0x83, 0xf8, + 0x4a, 0x07, 0xd5, 0x56, 0xab, 0x65, 0x27, 0x46, 0x76, 0x0a, 0xf0, 0x94, 0x44, 0xa2, 0x63, 0xa3, + 0x18, 0xec, 0x01, 0x54, 0x95, 0x3d, 0x6d, 0xa8, 0xb8, 0x36, 0xd2, 0xa5, 0xa6, 0x0b, 0xc2, 0xbe, + 0x04, 0xe8, 0xfd, 0x0f, 0x24, 0x8d, 0xca, 0xaf, 0x46, 0xdd, 0x87, 0xbd, 0x27, 0x34, 0x21, 0x41, + 0xd9, 0xd9, 0x5f, 0x00, 0xf6, 0x48, 0x2c, 0x9b, 0x25, 0xa3, 0xd8, 0xef, 0xdf, 0x64, 0xec, 0x63, + 0x38, 0x8a, 0x73, 0xbe, 0x83, 0x29, 0xfb, 0xae, 0x74, 0x35, 0x27, 0x4f, 0xe0, 0x03, 0x28, 0x8a, + 0x45, 0x10, 0x7f, 0xf1, 0xfe, 0xc5, 0x81, 0x22, 0x2b, 0x4b, 0xfb, 0xa7, 0x45, 0x40, 0xb6, 0x32, + 0xe2, 0x39, 0x14, 0x57, 0xd2, 0xd7, 0xdb, 0xf1, 0x32, 0x68, 0x27, 0x9b, 0xa2, 0xfd, 0xd8, 0x5b, + 0xd8, 0xca, 0x83, 0x3d, 0x82, 0xa2, 0x8c, 0xc3, 0x2a, 0x94, 0x7f, 0xf6, 0xc6, 0x9e, 0xff, 0xca, + 0x33, 0x6e, 0x61, 0x05, 0x8a, 0xb2, 0x9b, 0x8c, 0x1c, 0xee, 0x42, 0x49, 0x75, 0x86, 0x91, 0xc7, + 0x32, 0x14, 0x7a, 0x24, 0x8c, 0x02, 0x02, 0xec, 0xc4, 0xa2, 0x8d, 0x22, 0x7b, 0x08, 0x7b, 0xbf, + 0x70, 0x31, 0x18, 0x2d, 0x5f, 0xe4, 0x0c, 0x4a, 0x24, 0xd5, 0xe8, 0x67, 0x86, 0x54, 0x9f, 0x1d, + 0x1b, 0xd8, 0xa7, 0x70, 0xf0, 0x9c, 0x44, 0xe8, 0x0e, 0xa2, 0x65, 0x50, 0x03, 0xca, 0xd3, 0xf8, + 0x4a, 0x3f, 0x64, 0x72, 0x64, 0x5f, 0x41, 0xed, 0x19, 0x2d, 0x5e, 0xca, 0x07, 0xba, 0xe6, 0x6e, + 0xf8, 0xbe, 0x8f, 0x79, 0xf1, 0x77, 0x19, 0x0a, 0xcf, 0x5e, 0xf6, 0xf0, 0x06, 0xf6, 0xd6, 0x56, + 0x17, 0x1e, 0x6f, 0xd4, 0xe2, 0x4a, 0x6e, 0x4d, 0xd3, 0x54, 0x42, 0xb7, 0xae, 0x39, 0x66, 0xfe, + 0xf1, 0xcf, 0xbf, 0x7f, 0xe6, 0xeb, 0x88, 0xd6, 0xfc, 0xa1, 0x35, 0xd1, 0x2e, 0x37, 0x03, 0xc5, + 0xeb, 0xc3, 0xfe, 0xfa, 0xb2, 0xcb, 0xcc, 0x70, 0xa2, 0x32, 0x6c, 0xdf, 0x8c, 0xec, 0x44, 0xa5, + 0x38, 0xc2, 0x43, 0x99, 0x22, 0x4c, 0x7c, 0x74, 0x8e, 0x8e, 0x5e, 0x6d, 0x59, 0xe4, 0xdb, 0xe9, + 0x00, 0x26, 0x3c, 0x43, 0xf1, 0x00, 0x2b, 0x92, 0x27, 0x87, 0x12, 0xaf, 0xe3, 0x37, 0x45, 0x43, + 0x39, 0xaf, 0x2c, 0x0b, 0x33, 0x03, 0xcb, 0x4e, 0x15, 0xa3, 0x61, 0x1a, 0x92, 0xa1, 0x07, 0xd4, + 0x7a, 0xed, 0x3a, 0x6f, 0x2e, 0xd5, 0x98, 0x63, 0x37, 0x5d, 0x85, 0x59, 0xca, 0xea, 0x6b, 0x53, + 0x9e, 0x88, 0x3b, 0x54, 0xe0, 0x3d, 0xac, 0xae, 0x80, 0xb1, 0xab, 0x3b, 0x0d, 0xe3, 0xaf, 0x59, + 0xdd, 0x47, 0x99, 0x0a, 0x1b, 0x0a, 0x84, 0xcd, 0x0d, 0x85, 0x78, 0x0d, 0x95, 0x9e, 0xc7, 0x83, + 0x68, 0xe4, 0x8b, 0x4c, 0x71, 0x59, 0xd4, 0xba, 0xa2, 0xee, 0x63, 0x4d, 0x52, 0xa3, 0x84, 0xd2, + 0x81, 0xc2, 0x53, 0x12, 0x18, 0x0f, 0x5c, 0xba, 0xa3, 0x4c, 0x23, 0xbd, 0xd0, 0x9f, 0x77, 0x47, + 0xc5, 0x1f, 0xe2, 0x6d, 0x19, 0x2f, 0x87, 0xcc, 0x7a, 0x3d, 0xa6, 0xc5, 0xa3, 0x66, 0xf3, 0x0d, + 0x76, 0xd5, 0x0c, 0x69, 0x48, 0xba, 0xa3, 0x32, 0xa5, 0xdc, 0x55, 0xa8, 0x63, 0x73, 0x13, 0x75, + 0x99, 0x6b, 0xe2, 0x8b, 0x64, 0x10, 0x11, 0x15, 0x70, 0x6d, 0x7d, 0x65, 0x32, 0xb5, 0xbc, 0xe6, + 0x16, 0x79, 0x5f, 0x43, 0x49, 0x4d, 0x73, 0x66, 0xc9, 0xe2, 0x3c, 0x6b, 0x13, 0xcf, 0x6e, 0x7d, + 0x9e, 0x93, 0xad, 0xa0, 0x67, 0xfa, 0x1d, 0xad, 0xf0, 0xd6, 0xe4, 0xaf, 0xb7, 0x82, 0x1e, 0xfa, + 0xef, 0xef, 0xff, 0x7a, 0x6f, 0xe8, 0x8a, 0xd1, 0xac, 0xdf, 0x1e, 0xf8, 0x53, 0x6b, 0xea, 0x47, + 0xb3, 0x31, 0xb7, 0x06, 0x24, 0xd2, 0x7f, 0x75, 0xfa, 0x3b, 0xea, 0xd7, 0x17, 0xff, 0x05, 0x00, + 0x00, 0xff, 0xff, 0x3f, 0x16, 0x4d, 0xa0, 0x38, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -891,6 +977,8 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type KVSClient interface { + LivenessCheck(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*LivenessCheckResponse, error) + ReadinessCheck(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ReadinessCheckResponse, error) Node(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*NodeResponse, error) Join(ctx context.Context, in *JoinRequest, opts ...grpc.CallOption) (*empty.Empty, error) Cluster(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ClusterResponse, error) @@ -911,6 +999,24 @@ func NewKVSClient(cc *grpc.ClientConn) KVSClient { return &kVSClient{cc} } +func (c *kVSClient) LivenessCheck(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*LivenessCheckResponse, error) { + out := new(LivenessCheckResponse) + err := c.cc.Invoke(ctx, "/kvs.KVS/LivenessCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *kVSClient) ReadinessCheck(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*ReadinessCheckResponse, error) { + out := new(ReadinessCheckResponse) + err := c.cc.Invoke(ctx, "/kvs.KVS/ReadinessCheck", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *kVSClient) Node(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*NodeResponse, error) { out := new(NodeResponse) err := c.cc.Invoke(ctx, "/kvs.KVS/Node", in, out, opts...) @@ -1026,6 +1132,8 @@ func (c *kVSClient) Metrics(ctx context.Context, in *empty.Empty, opts ...grpc.C // KVSServer is the server API for KVS service. type KVSServer interface { + LivenessCheck(context.Context, *empty.Empty) (*LivenessCheckResponse, error) + ReadinessCheck(context.Context, *empty.Empty) (*ReadinessCheckResponse, error) Node(context.Context, *empty.Empty) (*NodeResponse, error) Join(context.Context, *JoinRequest) (*empty.Empty, error) Cluster(context.Context, *empty.Empty) (*ClusterResponse, error) @@ -1042,6 +1150,12 @@ type KVSServer interface { type UnimplementedKVSServer struct { } +func (*UnimplementedKVSServer) LivenessCheck(ctx context.Context, req *empty.Empty) (*LivenessCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LivenessCheck not implemented") +} +func (*UnimplementedKVSServer) ReadinessCheck(ctx context.Context, req *empty.Empty) (*ReadinessCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReadinessCheck not implemented") +} func (*UnimplementedKVSServer) Node(ctx context.Context, req *empty.Empty) (*NodeResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Node not implemented") } @@ -1077,6 +1191,42 @@ func RegisterKVSServer(s *grpc.Server, srv KVSServer) { s.RegisterService(&_KVS_serviceDesc, srv) } +func _KVS_LivenessCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(empty.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KVSServer).LivenessCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/kvs.KVS/LivenessCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVSServer).LivenessCheck(ctx, req.(*empty.Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _KVS_ReadinessCheck_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(empty.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KVSServer).ReadinessCheck(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/kvs.KVS/ReadinessCheck", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KVSServer).ReadinessCheck(ctx, req.(*empty.Empty)) + } + return interceptor(ctx, in, info, handler) +} + func _KVS_Node_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(empty.Empty) if err := dec(in); err != nil { @@ -1264,6 +1414,14 @@ var _KVS_serviceDesc = grpc.ServiceDesc{ ServiceName: "kvs.KVS", HandlerType: (*KVSServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "LivenessCheck", + Handler: _KVS_LivenessCheck_Handler, + }, + { + MethodName: "ReadinessCheck", + Handler: _KVS_ReadinessCheck_Handler, + }, { MethodName: "Node", Handler: _KVS_Node_Handler, diff --git a/protobuf/kvs.pb.gw.go b/protobuf/kvs.pb.gw.go index 4c1908e..40321a4 100644 --- a/protobuf/kvs.pb.gw.go +++ b/protobuf/kvs.pb.gw.go @@ -32,6 +32,42 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +func request_KVS_LivenessCheck_0(ctx context.Context, marshaler runtime.Marshaler, client KVSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq empty.Empty + var metadata runtime.ServerMetadata + + msg, err := client.LivenessCheck(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_KVS_LivenessCheck_0(ctx context.Context, marshaler runtime.Marshaler, server KVSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq empty.Empty + var metadata runtime.ServerMetadata + + msg, err := server.LivenessCheck(ctx, &protoReq) + return msg, metadata, err + +} + +func request_KVS_ReadinessCheck_0(ctx context.Context, marshaler runtime.Marshaler, client KVSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq empty.Empty + var metadata runtime.ServerMetadata + + msg, err := client.ReadinessCheck(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_KVS_ReadinessCheck_0(ctx context.Context, marshaler runtime.Marshaler, server KVSServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq empty.Empty + var metadata runtime.ServerMetadata + + msg, err := server.ReadinessCheck(ctx, &protoReq) + return msg, metadata, err + +} + func request_KVS_Node_0(ctx context.Context, marshaler runtime.Marshaler, client KVSClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq empty.Empty var metadata runtime.ServerMetadata @@ -411,6 +447,46 @@ func local_request_KVS_Metrics_0(ctx context.Context, marshaler runtime.Marshale // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. func RegisterKVSHandlerServer(ctx context.Context, mux *runtime.ServeMux, server KVSServer) error { + mux.Handle("GET", pattern_KVS_LivenessCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_KVS_LivenessCheck_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_KVS_LivenessCheck_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_KVS_ReadinessCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_KVS_ReadinessCheck_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_KVS_ReadinessCheck_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_KVS_Node_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -632,6 +708,46 @@ func RegisterKVSHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.C // "KVSClient" to call the correct interceptors. func RegisterKVSHandlerClient(ctx context.Context, mux *runtime.ServeMux, client KVSClient) error { + mux.Handle("GET", pattern_KVS_LivenessCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_KVS_LivenessCheck_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_KVS_LivenessCheck_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_KVS_ReadinessCheck_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_KVS_ReadinessCheck_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_KVS_ReadinessCheck_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_KVS_Node_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -816,6 +932,10 @@ func RegisterKVSHandlerClient(ctx context.Context, mux *runtime.ServeMux, client } var ( + pattern_KVS_LivenessCheck_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "liveness_check"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_KVS_ReadinessCheck_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "readiness_check"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_KVS_Node_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "node"}, "", runtime.AssumeColonVerbOpt(true))) pattern_KVS_Join_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "cluster", "id"}, "", runtime.AssumeColonVerbOpt(true))) @@ -836,6 +956,10 @@ var ( ) var ( + forward_KVS_LivenessCheck_0 = runtime.ForwardResponseMessage + + forward_KVS_ReadinessCheck_0 = runtime.ForwardResponseMessage + forward_KVS_Node_0 = runtime.ForwardResponseMessage forward_KVS_Join_0 = runtime.ForwardResponseMessage diff --git a/protobuf/kvs.proto b/protobuf/kvs.proto index 2db4302..1921fec 100644 --- a/protobuf/kvs.proto +++ b/protobuf/kvs.proto @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - syntax = "proto3"; import "google/protobuf/any.proto"; @@ -24,6 +10,18 @@ package kvs; option go_package = "github.com/mosuka/cete/protobuf"; service KVS { + rpc LivenessCheck (google.protobuf.Empty) returns (LivenessCheckResponse) { + option (google.api.http) = { + get: "/v1/liveness_check" + }; + } + + rpc ReadinessCheck (google.protobuf.Empty) returns (ReadinessCheckResponse) { + option (google.api.http) = { + get: "/v1/readiness_check" + }; + } + rpc Node (google.protobuf.Empty) returns (NodeResponse) { option (google.api.http) = { get: "/v1/node" @@ -78,6 +76,14 @@ service KVS { } } +message LivenessCheckResponse { + bool alive = 1; +} + +message ReadinessCheckResponse { + bool ready = 1; +} + message Metadata { string grpc_addr = 1; string http_addr = 2; diff --git a/registry/type.go b/registry/type.go index 52165d8..7dc13b0 100644 --- a/registry/type.go +++ b/registry/type.go @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package registry import ( diff --git a/server/grpc_gateway.go b/server/grpc_gateway.go index ab62bce..29f6c5d 100644 --- a/server/grpc_gateway.go +++ b/server/grpc_gateway.go @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package server import ( diff --git a/server/grpc_service.go b/server/grpc_service.go index 5691eb2..1ad08d9 100644 --- a/server/grpc_service.go +++ b/server/grpc_service.go @@ -173,6 +173,34 @@ func (s *GRPCService) stopWatchCluster() { } } +func (s *GRPCService) LivenessCheck(ctx context.Context, req *empty.Empty) (*protobuf.LivenessCheckResponse, error) { + resp := &protobuf.LivenessCheckResponse{} + + resp.Alive = true + + return resp, nil +} + +func (s *GRPCService) ReadinessCheck(ctx context.Context, req *empty.Empty) (*protobuf.ReadinessCheckResponse, error) { + resp := &protobuf.ReadinessCheckResponse{} + + timeout := 10 * time.Second + if err := s.raftServer.WaitForDetectLeader(timeout); err != nil { + s.logger.Error("missing leader node", zap.Error(err)) + return resp, status.Error(codes.Internal, err.Error()) + } + + if s.raftServer.State() == raft.Candidate || s.raftServer.State() == raft.Shutdown { + err := errors.ErrNodeNotReady + s.logger.Error(err.Error(), zap.Error(err)) + return resp, status.Error(codes.Internal, err.Error()) + } + + resp.Ready = true + + return resp, nil +} + func (s *GRPCService) Join(ctx context.Context, req *protobuf.JoinRequest) (*empty.Empty, error) { resp := &empty.Empty{} diff --git a/server/raft_fsm.go b/server/raft_fsm.go index aaf9dbe..3119f8b 100644 --- a/server/raft_fsm.go +++ b/server/raft_fsm.go @@ -1,17 +1,3 @@ -// Copyright (c) 2020 Minoru Osuka -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - package server import ( diff --git a/server/raft_server.go b/server/raft_server.go index d2fa03b..fa997ec 100644 --- a/server/raft_server.go +++ b/server/raft_server.go @@ -2,7 +2,6 @@ package server import ( "encoding/json" - "github.com/mosuka/cete/metric" "io/ioutil" "net" "os" @@ -17,6 +16,7 @@ import ( "github.com/hashicorp/raft" "github.com/mosuka/cete/errors" "github.com/mosuka/cete/marshaler" + "github.com/mosuka/cete/metric" "github.com/mosuka/cete/protobuf" "go.uber.org/zap" )