PG DB reroute

This commit is contained in:
2026-09-04 12:01:20 -05:00
parent f14e70b15c
commit e8078523be
12 changed files with 485 additions and 79 deletions
+5 -3
View File
@@ -8,6 +8,7 @@ import (
"github.com/nprasad2077/NBA_Go/models"
"github.com/nprasad2077/NBA_Go/utils/security"
"gorm.io/gorm"
"gorm.io/plugin/dbresolver"
)
// very small middleware: require header XAdminSecret == $ADMIN_SECRET
@@ -26,7 +27,8 @@ func RegisterKeyAdminRoutes(app *fiber.App, db *gorm.DB) {
admin.Get("/", func(c *fiber.Ctx) error {
var keys []models.APIKey
db.Find(&keys)
// Query write DB to guarantee immediate read-after-write consistency
db.Clauses(dbresolver.Write).Find(&keys)
return c.JSON(keys)
})
@@ -45,7 +47,7 @@ func RegisterKeyAdminRoutes(app *fiber.App, db *gorm.DB) {
Hash: security.HashKey(raw),
Label: body.Label,
}
db.Create(&key)
db.Clauses(dbresolver.Write).Create(&key)
// return ONLY the raw key once
return c.JSON(fiber.Map{
@@ -56,7 +58,7 @@ func RegisterKeyAdminRoutes(app *fiber.App, db *gorm.DB) {
admin.Post("/:id/revoke", func(c *fiber.Ctx) error {
id := c.Params("id")
db.Model(&models.APIKey{}).Where("id = ?", id).Update("revoked", true)
db.Clauses(dbresolver.Write).Model(&models.APIKey{}).Where("id = ?", id).Update("revoked", true)
return c.JSON(fiber.Map{"revoked": id})
})
}
+120
View File
@@ -0,0 +1,120 @@
package controllers
import (
"context"
"fmt"
"os"
"time"
"github.com/gofiber/fiber/v2"
"gorm.io/gorm"
"gorm.io/plugin/dbresolver"
)
type TargetHealth struct {
Status string `json:"status"`
Target string `json:"target"`
LatencyMs float64 `json:"latencyMs"`
Error string `json:"error,omitempty"`
}
type ReadinessResponse struct {
Status string `json:"status"`
Timestamp time.Time `json:"timestamp"`
Targets map[string]TargetHealth `json:"targets"`
}
// RegisterHealthRoutes mounts /healthz and /readyz probes
func RegisterHealthRoutes(app *fiber.App, db *gorm.DB) {
app.Get("/healthz", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{
"status": "UP",
"timestamp": time.Now().UTC(),
})
})
app.Get("/readyz", func(c *fiber.Ctx) error {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
targets := make(map[string]TargetHealth)
overallHealthy := true
writeHost := os.Getenv("DB_WRITE_HOST")
if writeHost == "" {
writeHost = "178.105.149.129"
}
writePort := os.Getenv("DB_WRITE_PORT")
if writePort == "" {
writePort = "5437"
}
readHost := os.Getenv("DB_READ_HOST")
if readHost == "" {
readHost = "178.105.149.129"
}
readPort := os.Getenv("DB_READ_PORT")
if readPort == "" {
readPort = "5438"
}
// Check Write Ingress (:5437)
writeTarget := fmt.Sprintf("%s:%s", writeHost, writePort)
writeStart := time.Now()
writeDB, err := db.Clauses(dbresolver.Write).DB()
if err != nil || writeDB == nil || writeDB.PingContext(ctx) != nil {
overallHealthy = false
errMsg := "Write ingress unreachable"
if err != nil {
errMsg = err.Error()
}
targets["db_write"] = TargetHealth{
Status: "DOWN",
Target: writeTarget,
Error: errMsg,
}
} else {
targets["db_write"] = TargetHealth{
Status: "UP",
Target: writeTarget,
LatencyMs: float64(time.Since(writeStart).Microseconds()) / 1000.0,
}
}
// Check Read Ingress (:5438)
readTarget := fmt.Sprintf("%s:%s", readHost, readPort)
readStart := time.Now()
readDB, err := db.Clauses(dbresolver.Read).DB()
if err != nil || readDB == nil || readDB.PingContext(ctx) != nil {
overallHealthy = false
errMsg := "Read ingress unreachable"
if err != nil {
errMsg = err.Error()
}
targets["db_read"] = TargetHealth{
Status: "DOWN",
Target: readTarget,
Error: errMsg,
}
} else {
targets["db_read"] = TargetHealth{
Status: "UP",
Target: readTarget,
LatencyMs: float64(time.Since(readStart).Microseconds()) / 1000.0,
}
}
statusCode := fiber.StatusOK
statusText := "UP"
if !overallHealthy {
statusCode = fiber.StatusServiceUnavailable
statusText = "DEGRADED"
}
return c.Status(statusCode).JSON(ReadinessResponse{
Status: statusText,
Timestamp: time.Now().UTC(),
Targets: targets,
})
})
}