feat: Add health checking feature to service registry, which periodically checks service status and deletes unhealthy services

This commit is contained in:
Alex Wellnitz 2025-02-11 16:35:48 +01:00
parent 9d4c10b392
commit ffbd653098
6 changed files with 57 additions and 6 deletions

View File

@ -17,6 +17,9 @@ func Start() {
// Migrate the schema // Migrate the schema
db.AutoMigrate(&models.Service{}) db.AutoMigrate(&models.Service{})
// Health Checking
go checkHealth()
// Init API Backend // Init API Backend
router := gin.Default() router := gin.Default()
router = registerRoutes(router) router = registerRoutes(router)

View File

@ -2,6 +2,8 @@ package generalnode
import ( import (
"fmt" "fmt"
"net/http"
"time"
"github.com/alexohneander/flotte/pkg/models" "github.com/alexohneander/flotte/pkg/models"
"github.com/alexohneander/flotte/pkg/types/request" "github.com/alexohneander/flotte/pkg/types/request"
@ -16,7 +18,43 @@ func registerSerivce(req request.ServiceRegister) error {
return err return err
} }
db.Create(&models.Service{Name: req.Name, NodeType: req.NodeType, Address: req.Address, Port: req.Port, Status: "running"}) err = db.Create(&models.Service{Name: req.Name, NodeType: req.NodeType, Address: req.Address, Port: req.Port, Status: "running"}).Error
if err != nil {
fmt.Println("failed to create service")
return err
}
return nil return nil
} }
func checkHealth() {
db, err := gorm.Open(sqlite.Open("flotte.db"), &gorm.Config{})
if err != nil {
fmt.Println("failed to connect database")
}
for {
var services []models.Service
db.Find(&services, models.Service{})
for _, service := range services {
resp, err := http.Get("http://" + service.Address + ":" + service.Port + "/ping")
if err != nil {
fmt.Println("error: ", err)
fmt.Println("delete service ", service.Name)
db.Unscoped().Delete(&service, service.ID)
}
if resp != nil && resp.StatusCode != 200 {
fmt.Println("delete service ", service.Name)
db.Unscoped().Delete(&service, service.ID)
}
if resp != nil && resp.StatusCode == 200 {
fmt.Println("service ", service.Name, " is healthy")
}
}
time.Sleep(30 * time.Second)
}
}

View File

@ -29,7 +29,7 @@ func registerAsMapNode() error {
Name: "map-01", Name: "map-01",
NodeType: "map", NodeType: "map",
Address: "localhost", Address: "localhost",
Port: 4000, Port: "4000",
} }
json_data, err := json.Marshal(serviceRegisterReq) json_data, err := json.Marshal(serviceRegisterReq)
@ -46,6 +46,11 @@ func registerAsMapNode() error {
return err return err
} }
if resp.StatusCode != http.StatusOK {
log.Fatal("failed to register as map-node")
return err
}
defer resp.Body.Close() defer resp.Body.Close()
var res map[string]interface{} var res map[string]interface{}

View File

@ -29,7 +29,7 @@ func registerAsReduceNode() error {
Name: "reduce-01", Name: "reduce-01",
NodeType: "reduce", NodeType: "reduce",
Address: "localhost", Address: "localhost",
Port: 4001, Port: "4001",
} }
json_data, err := json.Marshal(serviceRegisterReq) json_data, err := json.Marshal(serviceRegisterReq)
@ -46,6 +46,11 @@ func registerAsReduceNode() error {
return err return err
} }
if resp.StatusCode != http.StatusOK {
log.Fatal("failed to register as reduce-node")
return err
}
defer resp.Body.Close() defer resp.Body.Close()
var res map[string]interface{} var res map[string]interface{}

View File

@ -4,9 +4,9 @@ import "gorm.io/gorm"
type Service struct { type Service struct {
gorm.Model gorm.Model
Name string Name string `gorm:"unique"`
NodeType string NodeType string
Address string Address string
Port int Port string
Status string Status string
} }

View File

@ -4,5 +4,5 @@ type ServiceRegister struct {
Name string `json:"name"` Name string `json:"name"`
NodeType string `json:"nodeType"` NodeType string `json:"nodeType"`
Address string `json:"address"` Address string `json:"address"`
Port int `json:"port"` Port string `json:"port"`
} }