fix(sandbox/v2): LifecycleAction uses computer.BoxID instead of cfg.ID
cfg (ast.SandboxV2) is a pointer shared across all concurrent calls to the same Assistant. GetComputer writes cfg.ID = <random hex> for each oneshot request, so concurrent tasks overwrite each other's ID. When cleanup runs in defer, cfg.ID holds whichever task last wrote it — not the ID of the box this request created — so manager.Remove/Heartbeat silently fails with "sandbox: not found" and the container leaks. Fix: derive the box ID from computer.ComputerInfo().BoxID, which is the immutable b.id set at Create time and never mutated by concurrent callers. Made-with: Cursor
This commit is contained in:
parent
c26d764857
commit
cc0bb7e161
1 changed files with 9 additions and 3 deletions
|
|
@ -284,24 +284,30 @@ func resolveBox(
|
|||
|
||||
// LifecycleAction performs the post-request lifecycle operation based on policy.
|
||||
// Called in defer after executeSandboxStream completes.
|
||||
//
|
||||
// NOTE: cfg.ID must NOT be used here — it is a shared mutable field on the
|
||||
// Assistant struct and is overwritten by concurrent requests. The authoritative
|
||||
// box ID is computer.ComputerInfo().BoxID, which is set once when the Box is
|
||||
// created and never changes.
|
||||
func LifecycleAction(ctx context.Context, cfg *types.SandboxConfig, computer infra.Computer, manager *infra.Manager) {
|
||||
if computer == nil || cfg == nil {
|
||||
return
|
||||
}
|
||||
|
||||
info := computer.ComputerInfo()
|
||||
boxID := info.BoxID // use the box's own immutable ID, not cfg.ID
|
||||
|
||||
switch cfg.Lifecycle {
|
||||
case "oneshot":
|
||||
if info.Kind == "box" && manager != nil {
|
||||
if err := manager.Remove(ctx, cfg.ID); err != nil {
|
||||
log.Trace("[sandbox/v2] oneshot remove %s: %v", cfg.ID, err)
|
||||
if err := manager.Remove(ctx, boxID); err != nil {
|
||||
log.Trace("[sandbox/v2] oneshot remove %s: %v", boxID, err)
|
||||
}
|
||||
}
|
||||
|
||||
case "session", "longrunning":
|
||||
if info.Kind == "box" && manager != nil {
|
||||
manager.Heartbeat(cfg.ID, false, 0) // active=false: request finished, start idle timer
|
||||
manager.Heartbeat(boxID, false, 0) // active=false: request finished, start idle timer
|
||||
}
|
||||
|
||||
case "persistent":
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue