mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-09 13:21:42 +00:00
fix(gateway): drain async log queue on os._exit shutdown backstop
The QueueListener change routes rotating file handlers through an in-memory queue drained on a dedicated thread, with an atexit hook to flush on shutdown. But _exit_after_graceful_shutdown() uses os._exit, which bypasses atexit — so on the early-exit and #53107 hard-exit paths the queued records (including the shutdown reason) were silently lost. Explicitly flush_log_queue() before os._exit, and correct the now-stale comment that claimed handlers are synchronous with nothing pending.
This commit is contained in:
parent
eb0cc27201
commit
ac68a6411a
1 changed files with 16 additions and 4 deletions
|
|
@ -20239,16 +20239,28 @@ def _exit_after_graceful_shutdown(exit_code: int) -> None:
|
|||
released — so this is a no-op on the normal shutdown path and the actual
|
||||
cleanup on the early-exit paths.
|
||||
|
||||
Logging is not flushed here: the gateway's handlers are synchronous
|
||||
``RotatingFileHandler``s that write each record immediately (no
|
||||
``MemoryHandler``/``QueueHandler`` buffering), so there is nothing pending.
|
||||
Only stdio is buffered, so only stdio is flushed.
|
||||
Logging IS flushed here: the rotating file handlers are driven by an
|
||||
async ``QueueListener`` on a dedicated thread (see
|
||||
``hermes_logging._register_queued_handler``), so records emitted right
|
||||
before shutdown may still be sitting in the in-memory queue. ``os._exit``
|
||||
below bypasses ``atexit``, so the ``atexit``-registered listener drain
|
||||
never runs on this path — we must drain explicitly here or lose the last
|
||||
log lines (including the shutdown reason on the early-exit paths). Stdio
|
||||
is flushed too.
|
||||
"""
|
||||
for stream in (sys.stdout, sys.stderr):
|
||||
try:
|
||||
stream.flush()
|
||||
except Exception:
|
||||
pass
|
||||
# Drain the async log queue: os._exit bypasses atexit, so the listener's
|
||||
# atexit drain won't fire. flush_log_queue() no-ops when logging never
|
||||
# initialized a queue (e.g. very early aborts), so this is always safe.
|
||||
try:
|
||||
from hermes_logging import flush_log_queue
|
||||
flush_log_queue()
|
||||
except Exception:
|
||||
pass
|
||||
# Guaranteed cleanup chokepoint: os._exit skips atexit, and the early
|
||||
# SystemExit exit paths never run _stop_impl, so release here (idempotent).
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue