fix: Windows-specific reliability gap in the new timeout cleanup path… · openclaw/openclaw@897ca6a
clawsweeper
·
2026-04-30
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -2,8 +2,35 @@
|
2 | 2 | |
3 | 3 | package main |
4 | 4 | |
5 | | -import "os/exec" |
| 5 | +import ( |
| 6 | +"context" |
| 7 | +"errors" |
| 8 | +"os" |
| 9 | +"os/exec" |
| 10 | +"strconv" |
| 11 | +) |
| 12 | + |
| 13 | +var runWindowsTaskkill = func(pid int) error { |
| 14 | +ctx, cancel := context.WithTimeout(context.Background(), docsI18nCommandWaitDelay()) |
| 15 | +defer cancel() |
| 16 | +return exec.CommandContext(ctx, "taskkill.exe", "/T", "/F", "/PID", strconv.Itoa(pid)).Run() |
| 17 | +} |
6 | 18 | |
7 | 19 | func configureCodexPromptCommand(command *exec.Cmd) { |
| 20 | +command.Cancel = func() error { |
| 21 | +if command.Process == nil { |
| 22 | +return os.ErrProcessDone |
| 23 | + } |
| 24 | +if err := runWindowsTaskkill(command.Process.Pid); err != nil { |
| 25 | +killErr := command.Process.Kill() |
| 26 | +if errors.Is(killErr, os.ErrProcessDone) { |
| 27 | +return os.ErrProcessDone |
| 28 | + } |
| 29 | +if killErr != nil { |
| 30 | +return errors.Join(err, killErr) |
| 31 | + } |
| 32 | + } |
| 33 | +return nil |
| 34 | + } |
8 | 35 | command.WaitDelay = docsI18nCommandWaitDelay() |
9 | 36 | } |
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +//go:build windows |
| 2 | + |
| 3 | +package main |
| 4 | + |
| 5 | +import ( |
| 6 | +"errors" |
| 7 | +"os" |
| 8 | +"os/exec" |
| 9 | +"testing" |
| 10 | +"time" |
| 11 | +) |
| 12 | + |
| 13 | +func TestConfigureCodexPromptCommandWindowsCancelsProcessTree(t *testing.T) { |
| 14 | +t.Setenv(envDocsI18nCommandWaitDelay, "25ms") |
| 15 | +previousRunTaskkill := runWindowsTaskkill |
| 16 | +defer func() { runWindowsTaskkill = previousRunTaskkill }() |
| 17 | + |
| 18 | +var gotPID int |
| 19 | +runWindowsTaskkill = func(pid int) error { |
| 20 | +gotPID = pid |
| 21 | +return nil |
| 22 | + } |
| 23 | + |
| 24 | +command := exec.Command("codex") |
| 25 | +configureCodexPromptCommand(command) |
| 26 | +command.Process = &os.Process{Pid: 1234} |
| 27 | + |
| 28 | +if command.WaitDelay != 25*time.Millisecond { |
| 29 | +t.Fatalf("expected WaitDelay override, got %s", command.WaitDelay) |
| 30 | + } |
| 31 | +if command.Cancel == nil { |
| 32 | +t.Fatal("expected Cancel to be configured") |
| 33 | + } |
| 34 | +if err := command.Cancel(); err != nil { |
| 35 | +t.Fatalf("Cancel returned error: %v", err) |
| 36 | + } |
| 37 | +if gotPID != 1234 { |
| 38 | +t.Fatalf("expected taskkill for pid 1234, got %d", gotPID) |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +func TestConfigureCodexPromptCommandWindowsCancelBeforeStart(t *testing.T) { |
| 43 | +command := exec.Command("codex") |
| 44 | +configureCodexPromptCommand(command) |
| 45 | + |
| 46 | +if err := command.Cancel(); !errors.Is(err, os.ErrProcessDone) { |
| 47 | +t.Fatalf("expected os.ErrProcessDone, got %v", err) |
| 48 | + } |
| 49 | +} |
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。