From 77efa43179e9593401a5313af105447c1d1365c3 Mon Sep 17 00:00:00 2001 From: Maciej Bielecki Date: Thu, 12 Mar 2026 18:11:10 +0000 Subject: [PATCH] Fix ARM64 CI flaky test output ordering Move stream handler waits (stdout/stderr) to before status logging, ensuring all subprocess output is fully flushed before "success" or "skipped" messages are written. This eliminates a race condition where the main thread could write status messages before the output handler asyncs finished reading subprocess output. Co-Authored-By: Claude Opus 4.6 --- src/App.hs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/App.hs b/src/App.hs index 883d62a..1e74347 100644 --- a/src/App.hs +++ b/src/App.hs @@ -181,6 +181,17 @@ main = do then discardQuietBuffer appState -- Success: discard buffered output else flushQuietBuffer appState toplevelStderr -- Failure: show buffered output + -- Wait for output stream handlers to finish before logging status messages, + -- to ensure all subprocess output is flushed first. + timeoutStream appState "stdout" $ wait stdoutHandler + + -- We duplicate `subprocessStderr` before actually passing it to a + -- subprocess, so the original handle doesn't get closed by + -- `createProcess`. We must close it manually. + hClose appState.subprocessStderr + timeoutStream appState "stderr" $ wait stderrHandler + timeoutStream appState "stderr" $ wait subprocessStderrHandler + logDebug appState $ "Command " <> show (args.cmd : args.args) <> " exited with code " <> show exitCode logDebugParent m_parentRequestPipe $ "Subtask " <> toText jobName <> " finished with " <> show exitCode @@ -219,15 +230,6 @@ main = do branch <- getCurrentBranch appState RemoteCache.setLatestBuildHash appState s (toText appState.jobName) branch h.hash - timeoutStream appState "stdout" $ wait stdoutHandler - - -- We duplicate `subprocessStderr` before actually passing it to a - -- subprocess, so the original handle doesn't get closed by - -- `createProcess`. We must close it manually. - hClose appState.subprocessStderr - timeoutStream appState "stderr" $ wait stderrHandler - timeoutStream appState "stderr" $ wait subprocessStderrHandler - cancel cmdHandler -- Check if there's an existing status for this task/commit