Skip to content

Kill the process tree and keep the output on execution timeout - #64

Closed
slachiewicz wants to merge 4 commits into
mainfrom
agent/timeout-output-and-process-tree
Closed

slachiewicz wants to merge 4 commits into
mainfrom
agent/timeout-output-and-process-tree

Conversation

@slachiewicz

@slachiewicz slachiewicz commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

On timeout the forked executor now destroys the descendants of the started process before the process itself, and throws ExecutorTimeoutException, a subclass of ExecutorException that carries the last 64 KiB of the grabbed STDOUT and STDERR (stdOutTail(), stdErrTail()). The message keeps its Process timeout: prefix.

Only a tail, because a hung build may have logged far more than should be copied a second time and kept alive with an exception; it is read from the buffer without copying the rest. The grab buffer itself stays unbounded, as before; a caller that needs all of the output passes its own stdOut()/stdErr().

ProcessHandle is called by reflection rather than from src/main/java9: tests and other exploded class paths load from target/classes, where multi-release classes are never used. On Java 8 only the process itself is destroyed, as before.

Fixes #48
Fixes #58

Verified: with process.destroyForcibly() restored, timeoutDestroysTheProcessTree fails (the grandchild's heartbeat file grows from 92 to 110 bytes after the exception); with the whole buffer kept, timeoutKeepsOnlyTheTailOfLargeOutput fails with a 10,488,916-character tail.

Not run on Windows, where the started process is the cmd.exe running mvn.cmd; CI covers it.

ProcessHandle is reached by reflection, not from a src/main/java9 class: tests run
from target/classes, where multi-release classes are never loaded.
@slachiewicz slachiewicz added the bug Something isn't working label Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working wontfix This will not be worked on

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Forked executor discards the output it grabbed when an execution times out Forked executor leaves the process tree behind on timeout

1 participant