Baseline for the Kong replacement on api.riotpiao.com. Brings the working tree under version control for the first time: gateway source, the task board that drives the agent runs, test fixtures, and K8s manifests. Anchor the gateway ignore rule to the repo root. Unanchored, "gateway" also matched the cmd/gateway/ source directory, so the program entrypoint was excluded from every commit. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
91 lines
2.4 KiB
Go
91 lines
2.4 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"sync"
|
|
)
|
|
|
|
// HealthChecker provides health and readiness check information.
|
|
type HealthChecker struct {
|
|
mu sync.RWMutex
|
|
configValid bool
|
|
jwksHasFetched bool
|
|
authEnabled bool
|
|
}
|
|
|
|
// NewHealthChecker creates a new health checker instance.
|
|
func NewHealthChecker(configValid bool, authEnabled bool) *HealthChecker {
|
|
return &HealthChecker{
|
|
configValid: configValid,
|
|
jwksHasFetched: false,
|
|
authEnabled: authEnabled,
|
|
}
|
|
}
|
|
|
|
// MarkJWKSFetched marks that JWKS has been fetched successfully.
|
|
func (hc *HealthChecker) MarkJWKSFetched() {
|
|
hc.mu.Lock()
|
|
defer hc.mu.Unlock()
|
|
hc.jwksHasFetched = true
|
|
}
|
|
|
|
// IsReady checks if the server is ready to serve traffic.
|
|
// It returns true if:
|
|
// - Configuration is valid
|
|
// - If auth is enabled, JWKS has been fetched at least once
|
|
func (hc *HealthChecker) IsReady() bool {
|
|
hc.mu.RLock()
|
|
defer hc.mu.RUnlock()
|
|
|
|
if !hc.configValid {
|
|
return false
|
|
}
|
|
|
|
// If auth is enabled, we must have fetched JWKS at least once
|
|
if hc.authEnabled && !hc.jwksHasFetched {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// IsAlive returns true if the process is running.
|
|
// This is always true since if it weren't, we wouldn't be running this code.
|
|
func (hc *HealthChecker) IsAlive() bool {
|
|
return true
|
|
}
|
|
|
|
// LivenessHandler returns a handler for the /healthz endpoint.
|
|
// It returns 200 whenever the process is alive.
|
|
// It performs no network I/O.
|
|
func LivenessHandler(hc *HealthChecker) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if !hc.IsAlive() {
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte(`{"status":"alive"}`))
|
|
}
|
|
}
|
|
|
|
// ReadinessHandler returns a handler for the /readyz endpoint.
|
|
// It returns 200 only when configuration is valid and, if auth is enabled,
|
|
// JWKS has been fetched at least once.
|
|
// It returns non-2xx status while configuration is invalid or JWKS has never
|
|
// been fetched.
|
|
func ReadinessHandler(hc *HealthChecker) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
if !hc.IsReady() {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
w.Write([]byte(`{"status":"not_ready"}`))
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte(`{"status":"ready"}`))
|
|
}
|
|
}
|