feat: add deploy config for stabilization delay and probe timeouts
New config options: deploy.stabilization_delay (2s), deploy.tcp_probe_timeout (30s), deploy.http_probe_timeout (60s).
- commit
- 547a2f42452f4e38d202de7ac5ca95a873e4c628
- author
- brice · · 2026-03-02 16:44 UTC
- parent
- 0f1a5e4
- signature
- unsigned
2 files · +11 -3
M internal/app/run.go +6 -0
| @@ -1193,6 +1193,9 @@ func createContainerService(ctx context.Context, v *viper.Viper, cfg Config, svc | |||
| 1193 | 1193 | ReadinessDelay: v.GetDuration("deploy.readiness_delay"), | |
| 1194 | 1194 | ReadinessMode: v.GetString("deploy.readiness_mode"), | |
| 1195 | 1195 | HealthTimeout: v.GetDuration("deploy.health_timeout"), | |
| 1196 | + | StabilizationDelay: v.GetDuration("deploy.stabilization_delay"), | |
| 1197 | + | TCPProbeTimeout: v.GetDuration("deploy.tcp_probe_timeout"), | |
| 1198 | + | HTTPProbeTimeout: v.GetDuration("deploy.http_probe_timeout"), | |
| 1196 | 1199 | DrainDelay: v.GetDuration("deploy.drain_delay"), | |
| 1197 | 1200 | DrainMode: v.GetString("deploy.drain_mode"), | |
| 1198 | 1201 | DrainTimeout: v.GetDuration("deploy.drain_timeout"), | |
| @@ -2374,6 +2377,9 @@ func loadConfig(v *viper.Viper, configPath string) error { | |||
| 2374 | 2377 | v.SetDefault("deploy.readiness_delay", "5s") | |
| 2375 | 2378 | v.SetDefault("deploy.readiness_mode", "auto") | |
| 2376 | 2379 | v.SetDefault("deploy.health_timeout", "90s") | |
| 2380 | + | v.SetDefault("deploy.stabilization_delay", "2s") | |
| 2381 | + | v.SetDefault("deploy.tcp_probe_timeout", "30s") | |
| 2382 | + | v.SetDefault("deploy.http_probe_timeout", "60s") | |
| 2377 | 2383 | v.SetDefault("deploy.drain_mode", "auto") | |
| 2378 | 2384 | v.SetDefault("deploy.drain_timeout", "30s") | |
| 2379 | 2385 | ||
| @@ -1193,6 +1193,9 @@ func createContainerService(ctx context.Context, v *viper.Viper, cfg Config, svc | |||||
| 1193 | ReadinessDelay: v.GetDuration("deploy.readiness_delay"), | 1193 | ReadinessDelay: v.GetDuration("deploy.readiness_delay"), | ||
| 1194 | ReadinessMode: v.GetString("deploy.readiness_mode"), | 1194 | ReadinessMode: v.GetString("deploy.readiness_mode"), | ||
| 1195 | HealthTimeout: v.GetDuration("deploy.health_timeout"), | 1195 | HealthTimeout: v.GetDuration("deploy.health_timeout"), | ||
| 1196 | + | StabilizationDelay: v.GetDuration("deploy.stabilization_delay"), | |||
| 1197 | + | TCPProbeTimeout: v.GetDuration("deploy.tcp_probe_timeout"), | |||
| 1198 | + | HTTPProbeTimeout: v.GetDuration("deploy.http_probe_timeout"), | |||
| 1196 | DrainDelay: v.GetDuration("deploy.drain_delay"), | 1199 | DrainDelay: v.GetDuration("deploy.drain_delay"), | ||
| 1197 | DrainMode: v.GetString("deploy.drain_mode"), | 1200 | DrainMode: v.GetString("deploy.drain_mode"), | ||
| 1198 | DrainTimeout: v.GetDuration("deploy.drain_timeout"), | 1201 | DrainTimeout: v.GetDuration("deploy.drain_timeout"), | ||
| @@ -2374,6 +2377,9 @@ func loadConfig(v *viper.Viper, configPath string) error { | |||||
| 2374 | v.SetDefault("deploy.readiness_delay", "5s") | 2377 | v.SetDefault("deploy.readiness_delay", "5s") | ||
| 2375 | v.SetDefault("deploy.readiness_mode", "auto") | 2378 | v.SetDefault("deploy.readiness_mode", "auto") | ||
| 2376 | v.SetDefault("deploy.health_timeout", "90s") | 2379 | v.SetDefault("deploy.health_timeout", "90s") | ||
| 2380 | + | v.SetDefault("deploy.stabilization_delay", "2s") | |||
| 2381 | + | v.SetDefault("deploy.tcp_probe_timeout", "30s") | |||
| 2382 | + | v.SetDefault("deploy.http_probe_timeout", "60s") | |||
| 2377 | v.SetDefault("deploy.drain_mode", "auto") | 2383 | v.SetDefault("deploy.drain_mode", "auto") | ||
| 2378 | v.SetDefault("deploy.drain_timeout", "30s") | 2384 | v.SetDefault("deploy.drain_timeout", "30s") | ||
| 2379 | 2385 | ||||
M internal/usecase/container/service.go +5 -3
| @@ -48,7 +48,9 @@ type Config struct { | |||
| 48 | 48 | DrainDelayConfigured bool // True when deploy.drain_delay was explicitly configured | |
| 49 | 49 | DrainMode string // Drain strategy: auto, inflight, delay | |
| 50 | 50 | DrainTimeout time.Duration // Max wait for in-flight requests to drain | |
| 51 | - | StabilizationDelay time.Duration // Pause after traffic switch before verifying new container health | |
| 51 | + | StabilizationDelay time.Duration // Post-switch monitoring window (default 2s) | |
| 52 | + | TCPProbeTimeout time.Duration // TCP probe timeout (default 30s) | |
| 53 | + | HTTPProbeTimeout time.Duration // HTTP probe timeout (default 60s) | |
| 52 | 54 | } | |
| 53 | 55 | ||
| 54 | 56 | var tracer = otel.Tracer("gordon.container") | |
| @@ -2265,7 +2267,7 @@ func (s *Service) readinessCascade(ctx context.Context, containerID string, cont | |||
| 2265 | 2267 | ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig) | |
| 2266 | 2268 | if probeErr == nil && ip != "" && port > 0 { | |
| 2267 | 2269 | url := fmt.Sprintf("http://%s:%d%s", ip, port, healthPath) | |
| 2268 | - | timeout := cfg.HealthTimeout | |
| 2270 | + | timeout := cfg.HTTPProbeTimeout | |
| 2269 | 2271 | if timeout == 0 { | |
| 2270 | 2272 | timeout = 60 * time.Second | |
| 2271 | 2273 | } | |
| @@ -2282,7 +2284,7 @@ func (s *Service) readinessCascade(ctx context.Context, containerID string, cont | |||
| 2282 | 2284 | ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig) | |
| 2283 | 2285 | if probeErr == nil && ip != "" && port > 0 { | |
| 2284 | 2286 | addr := fmt.Sprintf("%s:%d", ip, port) | |
| 2285 | - | timeout := cfg.HealthTimeout | |
| 2287 | + | timeout := cfg.TCPProbeTimeout | |
| 2286 | 2288 | if timeout == 0 { | |
| 2287 | 2289 | timeout = 30 * time.Second | |
| 2288 | 2290 | } | |
| @@ -48,7 +48,9 @@ type Config struct { | |||||
| 48 | DrainDelayConfigured bool // True when deploy.drain_delay was explicitly configured | 48 | DrainDelayConfigured bool // True when deploy.drain_delay was explicitly configured | ||
| 49 | DrainMode string // Drain strategy: auto, inflight, delay | 49 | DrainMode string // Drain strategy: auto, inflight, delay | ||
| 50 | DrainTimeout time.Duration // Max wait for in-flight requests to drain | 50 | DrainTimeout time.Duration // Max wait for in-flight requests to drain | ||
| 51 | - | StabilizationDelay time.Duration // Pause after traffic switch before verifying new container health | 51 | + | StabilizationDelay time.Duration // Post-switch monitoring window (default 2s) |
| 52 | + | TCPProbeTimeout time.Duration // TCP probe timeout (default 30s) | |||
| 53 | + | HTTPProbeTimeout time.Duration // HTTP probe timeout (default 60s) | |||
| 52 | } | 54 | } | ||
| 53 | 55 | ||||
| 54 | var tracer = otel.Tracer("gordon.container") | 56 | var tracer = otel.Tracer("gordon.container") | ||
| @@ -2265,7 +2267,7 @@ func (s *Service) readinessCascade(ctx context.Context, containerID string, cont | |||||
| 2265 | ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig) | 2267 | ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig) | ||
| 2266 | if probeErr == nil && ip != "" && port > 0 { | 2268 | if probeErr == nil && ip != "" && port > 0 { | ||
| 2267 | url := fmt.Sprintf("http://%s:%d%s", ip, port, healthPath) | 2269 | url := fmt.Sprintf("http://%s:%d%s", ip, port, healthPath) | ||
| 2268 | - | timeout := cfg.HealthTimeout | 2270 | + | timeout := cfg.HTTPProbeTimeout |
| 2269 | if timeout == 0 { | 2271 | if timeout == 0 { | ||
| 2270 | timeout = 60 * time.Second | 2272 | timeout = 60 * time.Second | ||
| 2271 | } | 2273 | } | ||
| @@ -2282,7 +2284,7 @@ func (s *Service) readinessCascade(ctx context.Context, containerID string, cont | |||||
| 2282 | ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig) | 2284 | ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig) | ||
| 2283 | if probeErr == nil && ip != "" && port > 0 { | 2285 | if probeErr == nil && ip != "" && port > 0 { | ||
| 2284 | addr := fmt.Sprintf("%s:%d", ip, port) | 2286 | addr := fmt.Sprintf("%s:%d", ip, port) | ||
| 2285 | - | timeout := cfg.HealthTimeout | 2287 | + | timeout := cfg.TCPProbeTimeout |
| 2286 | if timeout == 0 { | 2288 | if timeout == 0 { | ||
| 2287 | timeout = 30 * time.Second | 2289 | timeout = 30 * time.Second | ||
| 2288 | } | 2290 | } | ||