mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-23 16:36:23 +00:00
fix(gateway): hard-exit on KeyboardInterrupt path too
The KeyboardInterrupt handler in run_gateway() was the only exit path that still used bare 'return' instead of _hard_exit_after_gateway_teardown(). While less common than service-managed restarts, a console Ctrl+C still leaves the process vulnerable to the same Python finalization hang on non-daemon worker threads (cron ThreadPoolExecutor jobs). Route it through the same backstop, with a 'return' guard for test stubs that don't raise on code 0 (production os._exit never returns).
This commit is contained in:
parent
c9ab8baf31
commit
4425ddd94d
3 changed files with 26 additions and 1 deletions
|
|
@ -4998,7 +4998,8 @@ def run_gateway(verbose: int = 0, quiet: bool = False, replace: bool = False, fo
|
|||
traceback=_traceback.format_exc(),
|
||||
)
|
||||
print("\nGateway stopped.")
|
||||
return
|
||||
_hard_exit_after_gateway_teardown(0)
|
||||
return # unreachable in production (os._exit); guard for test stubs
|
||||
except SystemExit as e:
|
||||
_exit_diag(
|
||||
"asyncio.run.SystemExit",
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ def test_run_gateway_exits_cleanly_on_keyboard_interrupt(monkeypatch, capsys):
|
|||
_install_fake_gateway_run(monkeypatch, fake_start_gateway)
|
||||
monkeypatch.setattr(gateway.asyncio, "run", fake_asyncio_run)
|
||||
|
||||
# KeyboardInterrupt now uses the same hard-exit backstop as all other
|
||||
# exit paths (instead of a bare ``return``). The test stub's
|
||||
# _exit_after_graceful_shutdown is a no-op for code 0, so run_gateway()
|
||||
# returns normally — but the real implementation would call os._exit(0).
|
||||
gateway.run_gateway()
|
||||
|
||||
out = capsys.readouterr().out
|
||||
|
|
|
|||
|
|
@ -85,3 +85,23 @@ def test_run_gateway_hard_exits_after_failed_return(monkeypatch):
|
|||
gateway_cli.run_gateway()
|
||||
|
||||
assert excinfo.value.code == 1
|
||||
|
||||
|
||||
def test_run_gateway_hard_exits_after_keyboard_interrupt(monkeypatch):
|
||||
"""KeyboardInterrupt (console Ctrl+C) must also hard-exit, not return.
|
||||
|
||||
A bare ``return`` would let Python finalization join non-daemon worker
|
||||
threads, the same wedge this backstop prevents on the other exit paths.
|
||||
"""
|
||||
gateway_cli = _prepare(monkeypatch)
|
||||
|
||||
def _fake_run(coro):
|
||||
coro.close()
|
||||
raise KeyboardInterrupt()
|
||||
|
||||
monkeypatch.setattr(gateway_cli.asyncio, "run", _fake_run)
|
||||
|
||||
with pytest.raises(_HardExitObserved) as excinfo:
|
||||
gateway_cli.run_gateway()
|
||||
|
||||
assert excinfo.value.code == 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue