detached 547a2f4

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
11931193 ReadinessDelay: v.GetDuration("deploy.readiness_delay"),
11941194 ReadinessMode: v.GetString("deploy.readiness_mode"),
11951195 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"),
11961199 DrainDelay: v.GetDuration("deploy.drain_delay"),
11971200 DrainMode: v.GetString("deploy.drain_mode"),
11981201 DrainTimeout: v.GetDuration("deploy.drain_timeout"),
@@ -2374,6 +2377,9 @@ func loadConfig(v *viper.Viper, configPath string) error {
23742377 v.SetDefault("deploy.readiness_delay", "5s")
23752378 v.SetDefault("deploy.readiness_mode", "auto")
23762379 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")
23772383 v.SetDefault("deploy.drain_mode", "auto")
23782384 v.SetDefault("deploy.drain_timeout", "30s")
23792385
@@ -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 {
4848 DrainDelayConfigured bool // True when deploy.drain_delay was explicitly configured
4949 DrainMode string // Drain strategy: auto, inflight, delay
5050 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)
5254 }
5355
5456 var tracer = otel.Tracer("gordon.container")
@@ -2265,7 +2267,7 @@ func (s *Service) readinessCascade(ctx context.Context, containerID string, cont
22652267 ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig)
22662268 if probeErr == nil && ip != "" && port > 0 {
22672269 url := fmt.Sprintf("http://%s:%d%s", ip, port, healthPath)
2268- timeout := cfg.HealthTimeout
2270+ timeout := cfg.HTTPProbeTimeout
22692271 if timeout == 0 {
22702272 timeout = 60 * time.Second
22712273 }
@@ -2282,7 +2284,7 @@ func (s *Service) readinessCascade(ctx context.Context, containerID string, cont
22822284 ip, port, probeErr := s.resolveContainerEndpoint(ctx, containerID, containerConfig)
22832285 if probeErr == nil && ip != "" && port > 0 {
22842286 addr := fmt.Sprintf("%s:%d", ip, port)
2285- timeout := cfg.HealthTimeout
2287+ timeout := cfg.TCPProbeTimeout
22862288 if timeout == 0 {
22872289 timeout = 30 * time.Second
22882290 }
@@ -48,7 +48,9 @@ type Config struct {
48 DrainDelayConfigured bool // True when deploy.drain_delay was explicitly configured48 DrainDelayConfigured bool // True when deploy.drain_delay was explicitly configured
49 DrainMode string // Drain strategy: auto, inflight, delay49 DrainMode string // Drain strategy: auto, inflight, delay
50 DrainTimeout time.Duration // Max wait for in-flight requests to drain50 DrainTimeout time.Duration // Max wait for in-flight requests to drain
51- StabilizationDelay time.Duration // Pause after traffic switch before verifying new container health51+ 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.HealthTimeout2270+ timeout := cfg.HTTPProbeTimeout
2269 if timeout == 0 {2271 if timeout == 0 {
2270 timeout = 60 * time.Second2272 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.HealthTimeout2287+ timeout := cfg.TCPProbeTimeout
2286 if timeout == 0 {2288 if timeout == 0 {
2287 timeout = 30 * time.Second2289 timeout = 30 * time.Second
2288 }2290 }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close