Added app package and health check funcs

This commit is contained in:
2025-01-04 11:23:24 -05:00
parent ce2a7ce221
commit bf3fa2c54c
7 changed files with 254 additions and 117 deletions

View File

@ -29,7 +29,7 @@ type HTTPFunc struct {
HandlerFunc http.HandlerFunc
}
func prepHTTPServer(ctx context.Context, handleFuncs ...HTTPFunc) *http.Server {
func prepHTTPServer(ctx context.Context, handleFuncs []HTTPFunc, hcFuncs ...HealthCheckFunc) *http.Server {
var (
cfg = config.MustFromCtx(ctx)
l = zerolog.Ctx(ctx)
@ -43,8 +43,9 @@ func prepHTTPServer(ctx context.Context, handleFuncs ...HTTPFunc) *http.Server {
mux.Handle(pattern, handler) // Associate pattern with handler
}
otelHandleFunc("/health", handleHealthCheckFunc(ctx))
otelHandleFunc("/", handleHealthCheckFunc(ctx))
healthChecks := handleHealthCheckFunc(ctx, hcFuncs...)
otelHandleFunc("/health", healthChecks)
otelHandleFunc("/", healthChecks)
for _, f := range handleFuncs {
otelHandleFunc(f.Path, f.HandlerFunc)
@ -85,8 +86,10 @@ func prepHTTPServer(ctx context.Context, handleFuncs ...HTTPFunc) *http.Server {
// Returns a shutdown func and a done channel if the
// server aborts abnormally. Panics on error.
func MustInitHTTPServer(ctx context.Context, funcs ...HTTPFunc) (func(context.Context) error, <-chan interface{}) {
shutdownFunc, doneChan, err := InitHTTPServer(ctx, funcs...)
func MustInitHTTPServer(ctx context.Context, funcs []HTTPFunc, hcFuncs ...HealthCheckFunc) (
func(context.Context) error, <-chan interface{},
) {
shutdownFunc, doneChan, err := InitHTTPServer(ctx, funcs, hcFuncs...)
if err != nil {
panic(err)
}
@ -95,7 +98,9 @@ func MustInitHTTPServer(ctx context.Context, funcs ...HTTPFunc) (func(context.Co
// Returns a shutdown func and a done channel if the
// server aborts abnormally. Returns error on failure to start
func InitHTTPServer(ctx context.Context, funcs ...HTTPFunc) (func(context.Context) error, <-chan interface{}, error) {
func InitHTTPServer(ctx context.Context, funcs []HTTPFunc, hcFuncs ...HealthCheckFunc) (
func(context.Context) error, <-chan interface{}, error,
) {
l := zerolog.Ctx(ctx)
doneChan := make(chan interface{})
@ -104,7 +109,7 @@ func InitHTTPServer(ctx context.Context, funcs ...HTTPFunc) (func(context.Contex
httpMeter = otel.GetMeter(ctx, "http")
httpTracer = otel.GetTracer(ctx, "http")
server = prepHTTPServer(ctx, funcs...)
server = prepHTTPServer(ctx, funcs, hcFuncs...)
go func() {
l.Debug().Msg("HTTP Server Started")

View File

@ -7,39 +7,47 @@ import (
"net/http"
"sync"
"time"
"github.com/rs/zerolog"
)
func handleHealthCheckFunc(_ context.Context) func(w http.ResponseWriter, r *http.Request) {
type HealthCheckFunc func(context.Context) error
func handleHealthCheckFunc(ctx context.Context, hcFuncs ...HealthCheckFunc) func(w http.ResponseWriter, r *http.Request) {
// Return http handle func
return func(w http.ResponseWriter, r *http.Request) {
var err error
var healthChecksFailed bool
var (
healthChecksFailed bool
errs error
hcWg sync.WaitGroup
)
// TODO: Insert useful health checks here
// For multiple checks, perform concurrently
// Consider using errors.Join() for multiple checks
var hcWg sync.WaitGroup
for range 5 {
hcWg.Add(1)
if len(hcFuncs) < 1 {
zerolog.Ctx(ctx).Warn().Msg("no health checks given responding with dummy 200")
hcFuncs = append(hcFuncs, dummyHealthCheck)
}
// Run all health check funcs concurrently
// log all errors
hcWg.Add(len(hcFuncs))
for _, hc := range hcFuncs {
go func() {
defer hcWg.Done()
err = errors.Join(err, dummyHealthCheck(r.Context()))
errs = errors.Join(errs, hc(ctx))
}()
}
hcWg.Wait()
if err != nil {
if errs != nil {
healthChecksFailed = true
}
// TODO: Friendly reminder...
err = errors.New("WARNING: Unimplemented health-check")
if healthChecksFailed {
w.WriteHeader(http.StatusInternalServerError)
}
if err != nil {
w.Write([]byte(err.Error()))
if errs != nil {
w.Write([]byte(errs.Error()))
} else {
w.Write([]byte("ok"))
}