Add timeout to container stop operations#121
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds a 30s Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
internal/container/stop.go (1)
19-27: Timeout is shared across all containers in the loop.The 10-second timeout applies to the entire function, not per container. If
containershas multiple entries, the timeout budget is consumed by earlier iterations, leaving progressively less time for subsequent containers. This could lead to inconsistent behavior where the first container stops successfully but later containers timeout.Consider either applying timeout per-container or scaling the timeout based on
len(containers).♻️ Option: Per-container timeout
func Stop(ctx context.Context, rt runtime.Runtime, sink output.Sink, containers []config.ContainerConfig) error { - ctx, cancel := context.WithTimeout(ctx, stopTimeout) - defer cancel() - for _, c := range containers { + stopCtx, cancel := context.WithTimeout(ctx, stopTimeout) name := c.Name() - running, err := rt.IsRunning(ctx, name) + running, err := rt.IsRunning(stopCtx, name) if err != nil { + cancel() return fmt.Errorf("checking %s running: %w", name, err) } if !running { + cancel() return fmt.Errorf("LocalStack is not running") } output.EmitSpinnerStart(sink, "Stopping LocalStack...") - if err := rt.Stop(ctx, name); err != nil { + if err := rt.Stop(stopCtx, name); err != nil { output.EmitSpinnerStop(sink) + cancel() return fmt.Errorf("failed to stop LocalStack: %w", name, err) } output.EmitSpinnerStop(sink) output.EmitSuccess(sink, "LocalStack stopped") + cancel() } return nil }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/container/stop.go` around lines 19 - 27, The timeout is currently shared across the entire loop so earlier iterations can consume the 10s budget; change to apply a per-container timeout by creating a new context with timeout inside the loop (and defer/call the cancel) before calling rt.IsRunning, or alternatively compute a scaled timeout like 10s * len(containers) and use that when creating the ctx; update the loop in stop.go where containers is iterated and rt.IsRunning(ctx, name) is invoked so each IsRunning call has its own timeout-bound context (ensure you call the cancel to avoid leaks).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@internal/container/stop.go`:
- Around line 19-27: The timeout is currently shared across the entire loop so
earlier iterations can consume the 10s budget; change to apply a per-container
timeout by creating a new context with timeout inside the loop (and defer/call
the cancel) before calling rt.IsRunning, or alternatively compute a scaled
timeout like 10s * len(containers) and use that when creating the ctx; update
the loop in stop.go where containers is iterated and rt.IsRunning(ctx, name) is
invoked so each IsRunning call has its own timeout-bound context (ensure you
call the cancel to avoid leaks).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 528e4621-2c30-44c8-bc62-d02211ab0ba0
📒 Files selected for processing (1)
internal/container/stop.go
68b082b to
3fca32a
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
internal/container/stop.go (1)
13-13: Make stop timeout injectable from the command boundaryLine 13 hardcodes
10sin domain logic. Consider passing timeout intoStop(...)so cmd-layer configuration can control it per environment.As per coding guidelines, "Do not call config.Get() from domain/business-logic packages; extract values at the command boundary (cmd/) and pass as explicit function arguments".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/container/stop.go` at line 13, The hardcoded stopTimeout constant (stopTimeout = 10 * time.Second) embeds a config value in domain logic; change the Stop function signature (e.g., Stop(ctx context.Context, timeout time.Duration) or Stop(ctx, timeout time.Duration) on the relevant type) to accept a timeout parameter instead of using stopTimeout, remove the package-level const, update internal uses inside Stop to use the passed timeout for cancellation/Timer logic, and update all callers to pass the desired timeout from the command layer (cmd/) where configuration is read.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/container/stop.go`:
- Around line 19-20: The shared context created with
containerCtx/containerCancel using stopTimeout causes IsRunning and the
subsequent Stop call (which invokes ContainerStop and ContainerRemove) to
compete for the same deadline and can make ContainerRemove falsely time out; fix
this by: 1) changing the function signature to accept an explicit timeout
parameter instead of using the package-level stopTimeout, 2) create and use
separate contexts for the pre-check (IsRunning) and for the actual stop/remove
operations (e.g., create a short-lived ctx for IsRunning and a fresh ctx for
Stop/ContainerStop/ContainerRemove) so the stop/remove gets a full timeout, and
3) ensure the timeout value is extracted at the command boundary and passed down
into this function.
---
Nitpick comments:
In `@internal/container/stop.go`:
- Line 13: The hardcoded stopTimeout constant (stopTimeout = 10 * time.Second)
embeds a config value in domain logic; change the Stop function signature (e.g.,
Stop(ctx context.Context, timeout time.Duration) or Stop(ctx, timeout
time.Duration) on the relevant type) to accept a timeout parameter instead of
using stopTimeout, remove the package-level const, update internal uses inside
Stop to use the passed timeout for cancellation/Timer logic, and update all
callers to pass the desired timeout from the command layer (cmd/) where
configuration is read.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 4ab01c40-e54c-4bf6-bcef-dd529a181bf5
📒 Files selected for processing (1)
internal/container/stop.go
e4693e7 to
a610317
Compare
|
Thanks, @carole-lavillonniere! Tried to address all three comments in a610317. Could you take another look when you're free? |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/container/stop.go`:
- Around line 19-31: The defer calls checkCancel() and stopCancel() inside the
loop cause context cancellation to be delayed until function exit; replace those
defers by calling checkCancel() immediately after the IsRunning(checkCtx, name)
result is handled and call stopCancel() immediately after the rt.Stop(stopCtx,
name) call completes (or on its error path) so each iteration's contexts are
cancelled before the next iteration; update the loop around IsRunning and Stop
to explicitly invoke checkCancel() and stopCancel() in all branches (success and
error) and keep IsRunning/Stop usage unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 17b7699f-c130-44d2-8a0f-c2176fff5afe
📒 Files selected for processing (1)
internal/container/stop.go
Fix DES-172