fix: periodic cProfile dump every 60s (survives hard kills)

Replace cProfile.runctx with Profile() + daemon thread that dumps
stats to disk every 60 seconds. Final dump on clean exit. Profile
data no longer lost on container stop, OOM, or SIGKILL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
user
2026-02-22 19:56:21 +01:00
parent c41035ceca
commit e0db0ad567

View File

@@ -193,10 +193,32 @@ def main(argv: list[str] | None = None) -> int:
if args.cprofile:
import cProfile
import threading
log.info("cProfile enabled, output: %s", args.cprofile)
cProfile.runctx("_run(bots)", globals(), {"bots": bots, "_run": _run}, args.cprofile)
log.info("profile saved to %s", args.cprofile)
prof = cProfile.Profile()
prof_path = args.cprofile
prof_interval = 60 # dump every 60 seconds
prof_stop = threading.Event()
def _periodic_dump():
while not prof_stop.wait(prof_interval):
try:
prof.dump_stats(prof_path)
except Exception:
pass
dumper = threading.Thread(target=_periodic_dump, daemon=True)
dumper.start()
log.info("cProfile enabled, output: %s (saves every %ds)",
prof_path, prof_interval)
prof.enable()
try:
_run(bots)
finally:
prof.disable()
prof_stop.set()
prof.dump_stats(prof_path)
log.info("profile saved to %s", prof_path)
else:
_run(bots)