fix: flush stdout writes in ConsoleLogger::writeDirect - #183
Closed
tx3stn wants to merge 1 commit into
Closed
Conversation
🎉 Bazel & CI Test Results
All Bazel configuration and CI tests passed! ✨ The build system and core tooling are working correctly. 🚀 Bazel remote cache is now enabled - future builds will be faster! Workflow: Valdi CI |
Collaborator
|
Thank you for the contribution, we're accepting and pulling this through our internal system. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Flush stdout writes in
ConsoleLogger::writeDirectwriteDirectnever flushes. It backsprocess.stdout.writein CLI apps, andstd::coutis fully buffered on anything that isn't a TTY, so piped output arrives in 4 KB bursts and a CLI killed by a signal loses it entirely. SIGTERM and SIGINT aren't handled, so a long-running CLI never flushes at all.log()already flushes viastd::endlso it is reliable but the raw one isn't.logalso prefixes lines with text like:which is noise for an end user. Calling
process.stdout.writefrom my logger lets me skip that and keep the formatted lines I actually want to show.My usecase: a long-running daemon built as a
valdi_cli_application, logging throughprocess.stdout.write.Every short-lived command that just does something and exits worked.
The daemon printed nothing. Same binary, output redirected to a file, killed after five seconds: zero bytes, no log lines. Re-running the identical command on a pty and reading while the process was still alive produced all of it. Terminal fine, redirected silent.
That is line buffering on a TTY against full buffering on a file, with no flush and no normal exit to trigger one. Under systemd it means
journalctlstays empty until 4 KB accumulates, andsystemctl stopdiscards whatever is pending.Example:
steps:
The keep-alive is what makes it reproducible. A CLI that exits on its own flushes stdio on the way out, so every existing example prints fine even when redirected. It needs two things: stdout that isn't a TTY, and a process that doesn't exit normally.
Limitations:
Working around them:
Batching in JS trades libc's invisible 4 KB buffer for one the caller sizes and flushes on its own schedule. Every
process.stdout.writecrosses the JS to native bridge, which costs more than thewriteit triggers, so anyone doing per-line writes for bulk output already hasa performance problemroom for improvement. Batching makes them faster than they were before this change.Type of Change
Testing
bazel test //...)Testing Details
Checklist
Related Issues
Additional Context