Replace Python handler-base library with Go module providing: - config: environment-based configuration - health: HTTP health/readiness server for k8s probes - natsutil: NATS/JetStream client with msgpack serialization - telemetry: OpenTelemetry tracing and metrics setup - clients: HTTP clients for LLM, embeddings, reranker, STT, TTS - handler: base Handler runner wiring NATS + health + telemetry Implements ADR-0061 Phase 1.
146 lines
4.1 KiB
Go
146 lines
4.1 KiB
Go
// Package config provides environment-based configuration for handler services.
|
|
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// Settings holds base configuration for all handler services.
|
|
// Values are loaded from environment variables with sensible defaults.
|
|
type Settings struct {
|
|
// Service identification
|
|
ServiceName string
|
|
ServiceVersion string
|
|
ServiceNamespace string
|
|
DeploymentEnv string
|
|
|
|
// NATS configuration
|
|
NATSURL string
|
|
NATSUser string
|
|
NATSPassword string
|
|
NATSQueueGroup string
|
|
|
|
// Redis/Valkey configuration
|
|
RedisURL string
|
|
RedisPassword string
|
|
|
|
// Milvus configuration
|
|
MilvusHost string
|
|
MilvusPort int
|
|
MilvusCollection string
|
|
|
|
// Service endpoints
|
|
EmbeddingsURL string
|
|
RerankerURL string
|
|
LLMURL string
|
|
TTSURL string
|
|
STTURL string
|
|
|
|
// OpenTelemetry configuration
|
|
OTELEnabled bool
|
|
OTELEndpoint string
|
|
OTELUseHTTP bool
|
|
|
|
// HyperDX configuration
|
|
HyperDXEnabled bool
|
|
HyperDXAPIKey string
|
|
HyperDXEndpoint string
|
|
|
|
// MLflow configuration
|
|
MLflowTrackingURI string
|
|
MLflowExperimentName string
|
|
MLflowEnabled bool
|
|
|
|
// Health check configuration
|
|
HealthPort int
|
|
HealthPath string
|
|
ReadyPath string
|
|
|
|
// Timeouts
|
|
HTTPTimeout time.Duration
|
|
NATSTimeout time.Duration
|
|
}
|
|
|
|
// Load creates a Settings populated from environment variables with defaults.
|
|
func Load() *Settings {
|
|
return &Settings{
|
|
ServiceName: getEnv("SERVICE_NAME", "handler"),
|
|
ServiceVersion: getEnv("SERVICE_VERSION", "1.0.0"),
|
|
ServiceNamespace: getEnv("SERVICE_NAMESPACE", "ai-ml"),
|
|
DeploymentEnv: getEnv("DEPLOYMENT_ENV", "production"),
|
|
|
|
NATSURL: getEnv("NATS_URL", "nats://nats.ai-ml.svc.cluster.local:4222"),
|
|
NATSUser: getEnv("NATS_USER", ""),
|
|
NATSPassword: getEnv("NATS_PASSWORD", ""),
|
|
NATSQueueGroup: getEnv("NATS_QUEUE_GROUP", ""),
|
|
|
|
RedisURL: getEnv("REDIS_URL", "redis://valkey.ai-ml.svc.cluster.local:6379"),
|
|
RedisPassword: getEnv("REDIS_PASSWORD", ""),
|
|
|
|
MilvusHost: getEnv("MILVUS_HOST", "milvus.ai-ml.svc.cluster.local"),
|
|
MilvusPort: getEnvInt("MILVUS_PORT", 19530),
|
|
MilvusCollection: getEnv("MILVUS_COLLECTION", "documents"),
|
|
|
|
EmbeddingsURL: getEnv("EMBEDDINGS_URL", "http://embeddings-predictor.ai-ml.svc.cluster.local"),
|
|
RerankerURL: getEnv("RERANKER_URL", "http://reranker-predictor.ai-ml.svc.cluster.local"),
|
|
LLMURL: getEnv("LLM_URL", "http://vllm-predictor.ai-ml.svc.cluster.local"),
|
|
TTSURL: getEnv("TTS_URL", "http://tts-predictor.ai-ml.svc.cluster.local"),
|
|
STTURL: getEnv("STT_URL", "http://whisper-predictor.ai-ml.svc.cluster.local"),
|
|
|
|
OTELEnabled: getEnvBool("OTEL_ENABLED", true),
|
|
OTELEndpoint: getEnv("OTEL_ENDPOINT", "http://opentelemetry-collector.observability.svc.cluster.local:4317"),
|
|
OTELUseHTTP: getEnvBool("OTEL_USE_HTTP", false),
|
|
|
|
HyperDXEnabled: getEnvBool("HYPERDX_ENABLED", false),
|
|
HyperDXAPIKey: getEnv("HYPERDX_API_KEY", ""),
|
|
HyperDXEndpoint: getEnv("HYPERDX_ENDPOINT", "https://in-otel.hyperdx.io"),
|
|
|
|
MLflowTrackingURI: getEnv("MLFLOW_TRACKING_URI", "http://mlflow.mlflow.svc.cluster.local:80"),
|
|
MLflowExperimentName: getEnv("MLFLOW_EXPERIMENT_NAME", ""),
|
|
MLflowEnabled: getEnvBool("MLFLOW_ENABLED", true),
|
|
|
|
HealthPort: getEnvInt("HEALTH_PORT", 8080),
|
|
HealthPath: getEnv("HEALTH_PATH", "/health"),
|
|
ReadyPath: getEnv("READY_PATH", "/ready"),
|
|
|
|
HTTPTimeout: getEnvDuration("HTTP_TIMEOUT", 60*time.Second),
|
|
NATSTimeout: getEnvDuration("NATS_TIMEOUT", 30*time.Second),
|
|
}
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
if v := os.Getenv(key); v != "" {
|
|
return v
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvInt(key string, fallback int) int {
|
|
if v := os.Getenv(key); v != "" {
|
|
if i, err := strconv.Atoi(v); err == nil {
|
|
return i
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvBool(key string, fallback bool) bool {
|
|
if v := os.Getenv(key); v != "" {
|
|
if b, err := strconv.ParseBool(v); err == nil {
|
|
return b
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvDuration(key string, fallback time.Duration) time.Duration {
|
|
if v := os.Getenv(key); v != "" {
|
|
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
|
return time.Duration(f * float64(time.Second))
|
|
}
|
|
}
|
|
return fallback
|
|
}
|