diff --git a/api/api.go b/api/api.go index d7e8915b..048e945b 100644 --- a/api/api.go +++ b/api/api.go @@ -24,7 +24,9 @@ type Options struct { GRPCNetwork string GRPCAddress string HTTPAddress string + Servers map[string]*network.Server } + type API struct { v1.GatewayDAdminAPIServiceServer diff --git a/api/grpc_server.go b/api/grpc_server.go index 073a1bfb..74bf30e8 100644 --- a/api/grpc_server.go +++ b/api/grpc_server.go @@ -5,11 +5,12 @@ import ( v1 "github.com/gatewayd-io/gatewayd/api/v1" "google.golang.org/grpc" + "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" ) // StartGRPCAPI starts the gRPC API. -func StartGRPCAPI(api *API) { +func StartGRPCAPI(api *API, healthchecker *HealthChecker) { listener, err := net.Listen(api.Options.GRPCNetwork, api.Options.GRPCAddress) if err != nil { api.Options.Logger.Err(err).Msg("failed to start gRPC API") @@ -18,6 +19,7 @@ func StartGRPCAPI(api *API) { grpcServer := grpc.NewServer() reflection.Register(grpcServer) v1.RegisterGatewayDAdminAPIServiceServer(grpcServer, api) + grpc_health_v1.RegisterHealthServer(grpcServer, healthchecker) if err := grpcServer.Serve(listener); err != nil { api.Options.Logger.Err(err).Msg("failed to start gRPC API") } diff --git a/api/healthcheck.go b/api/healthcheck.go new file mode 100644 index 00000000..42d53681 --- /dev/null +++ b/api/healthcheck.go @@ -0,0 +1,38 @@ +package api + +import ( + "context" + + "github.com/gatewayd-io/gatewayd/network" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/health/grpc_health_v1" + "google.golang.org/grpc/status" +) + +type HealthChecker struct { + grpc_health_v1.UnimplementedHealthServer + + Servers map[string]*network.Server +} + +func (h *HealthChecker) Check( + ctx context.Context, req *grpc_health_v1.HealthCheckRequest, +) (*grpc_health_v1.HealthCheckResponse, error) { + // Check if all servers are running + if liveness(h.Servers) { + return &grpc_health_v1.HealthCheckResponse{ + Status: grpc_health_v1.HealthCheckResponse_SERVING, + }, nil + } + + return &grpc_health_v1.HealthCheckResponse{ + Status: grpc_health_v1.HealthCheckResponse_NOT_SERVING, + }, nil +} + +func (h *HealthChecker) Watch( + req *grpc_health_v1.HealthCheckRequest, + server grpc_health_v1.Health_WatchServer, +) error { + return status.Error(codes.Unimplemented, "not implemented") +} diff --git a/api/utils.go b/api/utils.go new file mode 100644 index 00000000..8a1d09c2 --- /dev/null +++ b/api/utils.go @@ -0,0 +1,14 @@ +package api + +import ( + "github.com/gatewayd-io/gatewayd/network" +) + +func liveness(servers map[string]*network.Server) bool { + for _, v := range servers { + if !v.IsRunning() { + return false + } + } + return true +}