Improve HTTP timeout config

This commit is contained in:
2025-01-05 15:35:27 -05:00
parent 4a99f06987
commit c6514e0590
5 changed files with 80 additions and 28 deletions

View File

@ -2,10 +2,12 @@ package config
import (
"context"
"errors"
"flag"
"fmt"
"os"
"runtime/debug"
"time"
"github.com/caarlos0/env/v11"
"gopkg.in/yaml.v3"
@ -58,9 +60,52 @@ func loadConfig(configPath string) (*AppConfig, error) {
return nil, fmt.Errorf("could not parse environment variables: %w", err)
}
// Perform updates / enrichments
err := prepareConfig(&cfg)
if err != nil {
return nil, err
}
return &cfg, nil
}
func prepareConfig(cfg *AppConfig) error {
var errs error
// Set timeouts
if cfg.HTTP.ReadTimeout != "" {
if rT, err := time.ParseDuration(cfg.HTTP.ReadTimeout); err == nil {
cfg.HTTP.rT = &rT
} else {
errs = errors.Join(errs, err)
}
}
if cfg.HTTP.ReadTimeout != "" {
if wT, err := time.ParseDuration(cfg.HTTP.WriteTimeout); err == nil {
cfg.HTTP.wT = &wT
} else {
errs = errors.Join(errs, err)
}
}
if cfg.HTTP.IdleTimeout != "" {
if iT, err := time.ParseDuration(cfg.HTTP.IdleTimeout); err == nil {
cfg.HTTP.iT = &iT
} else {
errs = errors.Join(errs, err)
}
}
return errs
}
// Returns read timeout, write timeout, and idle timeout, in that order
// nil if unset
func (h *HTTPConfig) Timeouts() (*time.Duration, *time.Duration, *time.Duration) {
return h.rT, h.wT, h.iT
}
func getVersion() string {
if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version != "(devel)" {
return info.Main.Version

View File

@ -1,5 +1,7 @@
package config
import "time"
// Default Settings
var DefaultConfig = &AppConfig{
Environment: "development",
@ -12,7 +14,10 @@ var DefaultConfig = &AppConfig{
TimeFormat: TimeFormatLong,
},
HTTP: &HTTPConfig{
Listen: "127.0.0.1:8080",
Listen: "127.0.0.1:8080",
ReadTimeout: "10s",
WriteTimeout: "10s",
IdleTimeout: "1m",
},
OTEL: &OTELConfig{
Enabled: true,
@ -70,8 +75,13 @@ const (
// HTTP Configuration
type HTTPConfig struct {
Listen string `yaml:"listen,omitempty" env:"APP_HTTP_LISTEN"`
RequestTimeout int `yaml:"requestTimeout,omitempty" env:"APP_HTTP_REQUEST_TIMEOUT"`
Listen string `yaml:"listen,omitempty" env:"APP_HTTP_LISTEN"`
ReadTimeout string `yaml:"readTimeout" env:"APP_HTTP_READ_TIMEOUT"` // Go duration (e.g. 10s)
WriteTimeout string `yaml:"writeTimeout" env:"APP_HTTP_WRITE_TIMEOUT"` // Go duration (e.g. 10s)
IdleTimeout string `yaml:"idleTimeout" env:"APP_HTTP_IDLE_TIMEOUT"` // Go duration (e.g. 10s)
rT *time.Duration
wT *time.Duration
iT *time.Duration
}
// OTEL Configuration

View File

@ -17,11 +17,11 @@ import (
)
var (
httpMeter metric.Meter
httpTracer trace.Tracer
readTimeout = 10 * time.Second
writeTimeout = 10 * time.Second
idleTimeout = 15 * time.Second
httpMeter metric.Meter
httpTracer trace.Tracer
defReadTimeout = 10 * time.Second
defWriteTimeout = 10 * time.Second
defIdleTimeout = 15 * time.Second
)
type HTTPFunc struct {
@ -72,6 +72,23 @@ func prepHTTPServer(ctx context.Context, handleFuncs []HTTPFunc, hcFuncs ...Heal
}
}))
// Set timeouts from defaults, override
// with config timeouts if set
readTimeout := defReadTimeout
writeTimeout := defWriteTimeout
idleTimeout := defIdleTimeout
rT, wT, iT := cfg.HTTP.Timeouts()
if rT != nil {
readTimeout = *rT
}
if wT != nil {
writeTimeout = *wT
}
if iT != nil {
idleTimeout = *iT
}
return &http.Server{
Addr: cfg.HTTP.Listen,
ReadTimeout: readTimeout,