diff --git a/apps/backend/internal/agent/lifecycle/container.go b/apps/backend/internal/agent/lifecycle/container.go index 8f5d436a28..d162a1f740 100644 --- a/apps/backend/internal/agent/lifecycle/container.go +++ b/apps/backend/internal/agent/lifecycle/container.go @@ -270,7 +270,16 @@ func (cm *ContainerManager) waitForHealth(ctx context.Context, ctl *agentctl.Con if ctx.Err() != nil { return ctx.Err() } - time.Sleep(retryDelay) + // Cancelable wait that also skips the final retry's sleep — the loop + // only re-enters if i+1 < maxRetries, so the extra delay was just + // added latency on aborted launches. + if i+1 < maxRetries { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(retryDelay): + } + } } if lastErr != nil { diff --git a/apps/backend/internal/agent/lifecycle/executor_docker.go b/apps/backend/internal/agent/lifecycle/executor_docker.go index 379f72caaa..c15657d159 100644 --- a/apps/backend/internal/agent/lifecycle/executor_docker.go +++ b/apps/backend/internal/agent/lifecycle/executor_docker.go @@ -495,7 +495,13 @@ func waitForAgentctlHealthWith(ctx context.Context, ctl healthChecker, maxRetrie if ctx.Err() != nil { return ctx.Err() } - time.Sleep(retryDelay) + if i+1 < maxRetries { + select { + case <-ctx.Done(): + return ctx.Err() + case <-time.After(retryDelay): + } + } } if lastErr != nil {