add --cprofile flag with periodic dump

This commit is contained in:
Username
2026-02-24 13:18:10 +01:00
parent ee145b4071
commit f77375422a
2 changed files with 75 additions and 1 deletions

View File

@@ -22,6 +22,26 @@ tuimble --host mumble.example.com --user myname
- **toggle** — press to start, press again to stop (default)
- **hold** — hold key to transmit, release to stop (requires evdev)
## Profiling
```sh
tuimble --cprofile # saves to ~/.config/tuimble/profile.prof
tuimble --cprofile /tmp/tuimble.prof # saves to custom path
```
Profile data is dumped every 30 seconds and on exit, so snapshots
are available even after a crash or `kill`. Output is standard `.prof`
format:
```sh
python3 -m pstats /tmp/tuimble.prof # interactive explorer
# or install snakeviz for a browser-based flamegraph:
# pip install snakeviz && snakeviz /tmp/tuimble.prof
```
Note: cProfile captures the main thread only. Background workers
started with `@work(thread=True)` are not included.
## Configuration
See `~/.config/tuimble/config.toml`. All fields are optional;

View File

@@ -1,13 +1,67 @@
"""Entry point for tuimble."""
import argparse
import sys
def main():
parser = argparse.ArgumentParser(
prog="tuimble",
description="TUI client for Mumble",
)
parser.add_argument(
"--cprofile",
nargs="?",
const=None,
default=False,
metavar="FILE",
help="run under cProfile, saving to FILE "
"(default: ~/.config/tuimble/profile.prof)",
)
args = parser.parse_args()
from tuimble.app import TuimbleApp
app = TuimbleApp()
app.run()
if args.cprofile is not False:
_run_profiled(app, args.cprofile)
else:
app.run()
def _run_profiled(app, dest):
"""Run the app under cProfile with periodic 30s dumps."""
import cProfile
from pathlib import Path
from threading import Event, Thread
if dest is None:
from tuimble.config import CONFIG_DIR
dest = CONFIG_DIR / "profile.prof"
else:
dest = Path(dest)
dest.parent.mkdir(parents=True, exist_ok=True)
prof = cProfile.Profile()
stop = Event()
def _periodic_dump():
while not stop.wait(30):
prof.dump_stats(str(dest))
dumper = Thread(target=_periodic_dump, daemon=True)
dumper.start()
try:
prof.enable()
app.run()
finally:
prof.disable()
stop.set()
prof.dump_stats(str(dest))
if __name__ == "__main__":