Commit 0437746
authored
Fix deadlock when bundle script hooks write large stderr output (#5499)
## Why
Found during a full-repo review of the CLI. Bundle script hooks
(`experimental.scripts`) can deadlock a deploy forever. Hook output was
read sequentially: stdout to EOF first, then stderr. A hook that writes
more than the OS pipe buffer (about 64KiB) to stderr while stdout is
still open blocks on the stderr write and never closes stdout, so the
script and the CLI wait on each other indefinitely.
## Changes
Before, stderr was only read after stdout reached EOF (via
`io.MultiReader`); now stderr is drained concurrently, so the hook can
never block on a full stderr pipe. In `bundle/scripts/scripts.go`, a
goroutine spools stderr to memory while stdout is streamed line by line,
and the spooled stderr is logged after stdout EOF. This keeps the
existing stdout-then-stderr output order (no interleaving), so
observable output is unchanged for hooks that complete today. The line
logging loop is extracted into a `logOutput` helper and still emits a
final line without a trailing newline.
## Test plan
- [x] New unit test `TestExecuteLargeStderrOutputDoesNotDeadlock` writes
well over the pipe buffer to stderr before touching stdout; verified it
deadlocks against the previous implementation (killed by the test
context after 60s) and passes in ~0.05s with the fix
- [x] `go test -race ./bundle/scripts` passes, including the existing
no-trailing-newline test
- [x] Acceptance tests under `acceptance/bundle/scripts` pass for both
engines with no output changes
- [x] `./task fmt-q`, `./task lint-q`, `./task checks` all clean
This pull request and its description were written by Isaac.1 parent 26d315c commit 0437746
2 files changed
Lines changed: 66 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
46 | | - | |
| 47 | + | |
47 | 48 | | |
48 | 49 | | |
49 | 50 | | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
53 | 78 | | |
54 | 79 | | |
55 | 80 | | |
| |||
60 | 85 | | |
61 | 86 | | |
62 | 87 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | 88 | | |
71 | 89 | | |
72 | | - | |
| 90 | + | |
73 | 91 | | |
74 | 92 | | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
| 93 | + | |
81 | 94 | | |
82 | 95 | | |
83 | | - | |
| 96 | + | |
84 | 97 | | |
85 | 98 | | |
86 | 99 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
| 6 | + | |
5 | 7 | | |
| 8 | + | |
6 | 9 | | |
7 | 10 | | |
8 | 11 | | |
| |||
38 | 41 | | |
39 | 42 | | |
40 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
0 commit comments