Health and Readiness Checks
Liveness answers “is this process running?” Readiness answers “can this process serve real traffic?” Keeping them separate prevents a temporary database outage from restarting a healthy process.
mkdir zinc-healthcd zinc-healthgo mod init example.com/zinc-healthgo get github.com/0mjs/zincgo get github.com/jackc/pgx/v5/stdlibApplication
Section titled “Application”package main
import ( "context" "database/sql" "log" "time"
"github.com/0mjs/zinc" _ "github.com/jackc/pgx/v5/stdlib")
func main() { db, err := sql.Open("pgx", "postgres://localhost/app?sslmode=disable") if err != nil { log.Fatal(err) } defer db.Close()
app := zinc.New()
app.Get("/live", func(c *zinc.Context) error { return c.JSON(zinc.Map{"status": "up"}) })
app.Get("/ready", func(c *zinc.Context) error { ctx, cancel := context.WithTimeout(c.Context(), 500*time.Millisecond) defer cancel()
if err := db.PingContext(ctx); err != nil { return c.Status(zinc.StatusServiceUnavailable).JSON(zinc.Map{ "status": "unavailable", "database": "down", }) }
return c.JSON(zinc.Map{ "status": "ready", "database": "up", }) })
log.Fatal(app.Listen(":8080"))}Swap the PostgreSQL driver and connection string for the database your service already uses; the Zinc handlers are unchanged.
Probe it
Section titled “Probe it”curl -i http://localhost:8080/livecurl -i http://localhost:8080/readyPoint an orchestrator’s liveness probe at /live and readiness probe at
/ready. Keep readiness checks bounded with short timeouts, and include only
dependencies required to serve traffic.
