bench: exit the sampler quietly when its reader goes away

Piping `telemetry.py --run` into anything that stops reading first — head, or
the campaign shutting the sampler down — raised BrokenPipeError and printed a
traceback. Under ab_repeat that traceback lands in telemetry.err, where it
reads as "telemetry is broken" rather than "telemetry ended normally", and
telemetry.err is exactly the file someone checks when the clock record looks
short.

Swallowing the exception alone is not enough: the interpreter flushes stdout
again on exit and emits a second "Exception ignored" to stderr, so stdout is
pointed at devnull the way CPython documents.
This commit is contained in:
Aharrypotter committed 2026-09-10 16:10:15 +08:00
1 parent 4329b0c835
commit 551ffbbb77
1 file changed
+11
+11
View File
@@ -93,6 +93,17 @@ def main(argv: Optional[List[str]] = None) -> int:
return run(backend, device, args.interval)
except KeyboardInterrupt:
return 0
except BrokenPipeError:
# 读端先走(管给 head,或 campaign 结束时收掉)。这是正常终止,不该在
# telemetry.err 里留一段 traceback 让人以为遥测本身坏了。按 CPython 的
# 惯用做法把 stdout 指到 devnull——只吞异常不够,解释器退出时还会 flush
# 一次,再抛一条 "Exception ignored" 到 stderr。
try:
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, sys.stdout.fileno())
except Exception:
pass
return 0
if __name__ == "__main__":