Found during the 15-way review of #119 (histogram-race fix), but pre-existing — reproduced on master too, so filing separately.
If the process's stdout/stderr is a pipe whose consumer stops draining (a wedged terminal, a run-remote/SSH stream stall, a full CI log buffer), ftsb_redisearch can block forever inside a log.Printf and never write the --json-out-file result — even though all operations completed.
There are two blocking log sites, both before the result is persisted:
- The periodic
report() progress line (unbounded volume — one line per --reporting-period), and
summary(), which logs the human-readable summary before it marshals+writes the JSON result file.
Reproduced deterministically (both master and the #116 branch): --duration 4s --reporting-period 1ms, output to a mkfifo with no reader → the reporter fills the 64 KB pipe buffer mid-run and blocks; at shutdown the process hangs and no JSON file is written (timeout kills it). A regular-file or drained-pipe destination always completes.
Operational impact: in the on-the-fly-EC2 model a hung run yields no result and leaves the bench-server EC2 billing until manually destroyed.
Suggested fix (robustness, independent of the concurrency work):
Note: --log-file does not help — main.go uses io.MultiWriter(os.Stdout, f), so a stalled stdout still blocks the combined write.
Found during the 15-way review of #119 (histogram-race fix), but pre-existing — reproduced on master too, so filing separately.
If the process's stdout/stderr is a pipe whose consumer stops draining (a wedged terminal, a
run-remote/SSH stream stall, a full CI log buffer),ftsb_redisearchcan block forever inside alog.Printfand never write the--json-out-fileresult — even though all operations completed.There are two blocking log sites, both before the result is persisted:
report()progress line (unbounded volume — one line per--reporting-period), andsummary(), which logs the human-readable summary before it marshals+writes the JSON result file.Reproduced deterministically (both master and the #116 branch):
--duration 4s --reporting-period 1ms, output to amkfifowith no reader → the reporter fills the 64 KB pipe buffer mid-run and blocks; at shutdown the process hangs and no JSON file is written (timeoutkills it). A regular-file or drained-pipe destination always completes.Operational impact: in the on-the-fly-EC2 model a hung run yields no result and leaves the bench-server EC2 billing until manually destroyed.
Suggested fix (robustness, independent of the concurrency work):
--json-out-fileresult before the blocking console logs insummary(), so the result is always persisted.Note:
--log-filedoes not help —main.gousesio.MultiWriter(os.Stdout, f), so a stalled stdout still blocks the combined write.