Added app package and health check funcs
This commit is contained in:
@ -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")
|
||||
|
@ -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"))
|
||||
}
|
||||
|
Reference in New Issue
Block a user