From 84ed5e5b3ae3768b048a2d537051672c05b987de Mon Sep 17 00:00:00 2001 From: He-Pin Date: Sat, 20 Jun 2026 16:32:28 +0800 Subject: [PATCH] fix(client): wait for output pump before exit to prevent truncated stdout Motivation: E2ETests.secondInvocationReusesServer was flaky because the output pumper thread (outThread) is a daemon thread. After serverLock.await() returns, the main thread immediately reads the exit code and calls System.exit(), killing the daemon thread before it finishes draining the socket buffer to stdout. This results in empty or truncated output. Modification: Add outThread.join(5_000) after serverLock.await() in SjsonnetClientMain.java. The server closes its end of the socket before releasing serverLock, so by the time await() returns, the socket has EOF waiting. The join gives the output pumper thread time to read all remaining data and terminate naturally before the client process exits. Result: E2E tests pass consistently across 5+ consecutive runs (previously flaky). --- .../client/src/sjsonnet/client/SjsonnetClientMain.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sjsonnet/client/src/sjsonnet/client/SjsonnetClientMain.java b/sjsonnet/client/src/sjsonnet/client/SjsonnetClientMain.java index fd422868..2867a21e 100644 --- a/sjsonnet/client/src/sjsonnet/client/SjsonnetClientMain.java +++ b/sjsonnet/client/src/sjsonnet/client/SjsonnetClientMain.java @@ -131,6 +131,13 @@ public static int run(String lockBase, locks.serverLock.await(); + // The server closes its end of the socket before releasing serverLock, + // so the output pumper will see EOF. Wait for it to finish so that all + // output is fully written to stdout/stderr before we exit. Without this + // join, System.exit() kills the daemon thread mid-pump, which can result + // in empty or truncated output (flaky test: secondInvocationReusesServer). + outThread.join(5_000); + try { String content = Files.readString(Path.of(lockBase, "exitCode"), StandardCharsets.UTF_8); return Integer.parseInt(content.trim());