From 259f529f0908075bd1015dd9e3877878bdf80e90 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 2 Sep 2026 21:02:19 -0700 Subject: [PATCH] =?UTF-8?q?refactor(hermes=5Fcli):=20gateway.py=20run=5Fga?= =?UTF-8?q?teway=20region=20=E2=80=94=20shared=20tty/detached=20probes,=20?= =?UTF-8?q?collapsed=20exit-code=20ladder,=20storm-backoff=20env=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hermes_cli/gateway.py | 115 +++++++++++++----------------------------- 1 file changed, 36 insertions(+), 79 deletions(-) diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index 2dd2b79fa1..54b8212346 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -1940,20 +1940,26 @@ def _windows_scheduled_task_supervises(task_name: str) -> bool: return state in _WINDOWS_TASK_SUPERVISOR_STATES +def _gateway_detached_env() -> bool: + return _truthy_env(os.getenv("HERMES_GATEWAY_DETACHED")) + + +def _stdin_is_tty() -> bool | None: + """``sys.stdin.isatty()``; None when stdin is closed/invalid.""" + try: + return bool(sys.stdin and sys.stdin.isatty()) + except (ValueError, OSError): + return None + + def _windows_gateway_should_absorb_console_controls() -> bool: """True for detached Windows gateway runs that should ignore Ctrl+C (``HERMES_GATEWAY_DETACHED=1`` or no interactive stdin); foreground runs stay interruptible.""" if not is_windows(): return False - - detached = os.getenv("HERMES_GATEWAY_DETACHED", "").strip().lower() - if detached in {"1", "true", "yes", "on"}: - return True - - try: - return not bool(sys.stdin and sys.stdin.isatty()) - except (ValueError, OSError): + if _gateway_detached_env(): return True + return not _stdin_is_tty() def _windows_console_window_attached() -> bool | None: @@ -1974,12 +1980,7 @@ def _windows_gateway_breakaway_state() -> bool | None: return None from hermes_cli._subprocess_compat import _WINDOWS_GATEWAY_BREAKAWAY_ENV - value = os.environ.pop(_WINDOWS_GATEWAY_BREAKAWAY_ENV, None) - if value == "1": - return True - if value == "0": - return False - return None + return {"1": True, "0": False}.get(os.environ.pop(_WINDOWS_GATEWAY_BREAKAWAY_ENV, None)) # ============================================================================= @@ -4765,9 +4766,7 @@ def _guard_existing_gateway_process_conflict(replace: bool = False) -> None: def _guard_official_docker_root_gateway() -> None: """Refuse gateway startup when the official Docker privilege drop was bypassed.""" - if not hasattr(os, "geteuid") or os.geteuid() != 0: - return - if _truthy_env(os.getenv("HERMES_ALLOW_ROOT_GATEWAY")): + if not hasattr(os, "geteuid") or os.geteuid() != 0 or _truthy_env(os.getenv("HERMES_ALLOW_ROOT_GATEWAY")): return if not _is_official_docker_checkout(): return @@ -4796,11 +4795,8 @@ def _apply_startup_watchdog_config() -> None: """ try: from hermes_startup_watchdog import ( - ENV_STARTUP_WATCHDOG, - ENV_STARTUP_WATCHDOG_TIMEOUT_S, - arm_startup_watchdog, - disarm_startup_watchdog, - startup_watchdog_disabled, + ENV_STARTUP_WATCHDOG, ENV_STARTUP_WATCHDOG_TIMEOUT_S, arm_startup_watchdog, + disarm_startup_watchdog, startup_watchdog_disabled, ) _sw_timeout_bridged = False try: @@ -4809,7 +4805,7 @@ def _apply_startup_watchdog_config() -> None: if ENV_STARTUP_WATCHDOG not in os.environ and not _gw_cfg.get("startup_watchdog", True): os.environ[ENV_STARTUP_WATCHDOG] = "0" _sw_timeout = _gw_cfg.get("startup_watchdog_timeout_seconds") - if (ENV_STARTUP_WATCHDOG_TIMEOUT_S not in os.environ and _sw_timeout is not None): + if ENV_STARTUP_WATCHDOG_TIMEOUT_S not in os.environ and _sw_timeout is not None: os.environ[ENV_STARTUP_WATCHDOG_TIMEOUT_S] = str(_sw_timeout) _sw_timeout_bridged = True except Exception: @@ -4859,19 +4855,12 @@ def _make_exit_diag(): log_dir = _ghh() / "logs" log_dir.mkdir(parents=True, exist_ok=True) - ts = _dt.now(_tz.utc).isoformat() line = { - "ts": ts, - "tag": tag, - "pid": os.getpid(), - "python": sys.version.split()[0], - "platform": sys.platform, - **extra, + "ts": _dt.now(_tz.utc).isoformat(), "tag": tag, "pid": os.getpid(), + "python": sys.version.split()[0], "platform": sys.platform, **extra, } - import json as _json - with open(log_dir / "gateway-exit-diag.log", "a", encoding="utf-8") as f: - f.write(_json.dumps(line, default=str) + "\n") + f.write(json.dumps(line, default=str) + "\n") except Exception: pass # never let the diagnostic itself crash the gateway @@ -4885,8 +4874,6 @@ def _respawn_storm_backoff() -> None: HERMES_GATEWAY_START_WINDOW_S override. max_starts <= 0 disables. Never blocks startup. """ try: - import time as _time - from gateway.status import record_start_and_check_storm _max_starts = 5 @@ -4905,28 +4892,18 @@ def _respawn_storm_backoff() -> None: except Exception: pass try: - _env_starts = os.getenv("HERMES_GATEWAY_MAX_STARTS") - if _env_starts is not None: - _max_starts = int(_env_starts) - except ValueError: + _max_starts = int(os.environ["HERMES_GATEWAY_MAX_STARTS"]) + except (KeyError, ValueError): pass try: - _env_win = os.getenv("HERMES_GATEWAY_START_WINDOW_S") - if _env_win is not None: - _win = float(_env_win) - except ValueError: + _win = float(os.environ["HERMES_GATEWAY_START_WINDOW_S"]) + except (KeyError, ValueError): pass - _storm = ( - record_start_and_check_storm(max_starts=_max_starts, window_s=_win) - if _max_starts > 0 - else None - ) + _storm = record_start_and_check_storm(max_starts=_max_starts, window_s=_win) if _max_starts > 0 else None if _storm is not None: logger.warning( "Gateway (re)started %d times in %.0fs — backing off %.0fs to break a respawn storm.", - _storm.count, - _storm.window_s, - _storm.backoff_s, + _storm.count, _storm.window_s, _storm.backoff_s, ) # Tell the startup watchdog the backoff sleep is intentional, not a parked deadlock. try: @@ -4935,7 +4912,7 @@ def _respawn_storm_backoff() -> None: kick_startup_watchdog(extra_s=_storm.backoff_s) except Exception: pass - _time.sleep(_storm.backoff_s) + time.sleep(_storm.backoff_s) except Exception as _be: logger.debug("respawn-storm breaker check failed (non-fatal): %s", _be) @@ -4953,12 +4930,8 @@ def run_gateway(verbose: int = 0, quiet: bool = False, replace: bool = False, fo # Detached Windows runs (HERMES_GATEWAY_DETACHED=1, or non-TTY for older wrappers) ignore # console-control broadcasts from sibling CLIs; foreground runs keep Ctrl+C-to-stop. - try: - _stdin_is_tty = bool(sys.stdin and sys.stdin.isatty()) - except (ValueError, OSError): - _stdin_is_tty = False + stdin_is_tty = bool(_stdin_is_tty()) _console_window_attached = _windows_console_window_attached() - _gateway_detached = os.getenv("HERMES_GATEWAY_DETACHED", "").strip().lower() in {"1", "true", "yes", "on"} _breakaway = _windows_gateway_breakaway_state() _absorb = _windows_gateway_should_absorb_console_controls() if _absorb: @@ -4990,14 +4963,9 @@ def run_gateway(verbose: int = 0, quiet: bool = False, replace: bool = False, fo _exit_diag = _make_exit_diag() _exit_diag( - "gateway.start", - replace=replace, - argv=sys.argv, - stdin_is_tty=_stdin_is_tty, - console_window_attached=_console_window_attached, - detached=_gateway_detached, - breakaway=_breakaway, - absorb_windows_console_controls=_absorb, + "gateway.start", replace=replace, argv=sys.argv, stdin_is_tty=stdin_is_tty, + console_window_attached=_console_window_attached, detached=_gateway_detached_env(), + breakaway=_breakaway, absorb_windows_console_controls=_absorb, ) _atexit.register(lambda: _exit_diag("atexit.hook", sys_exc=repr(sys.exc_info()))) @@ -5021,22 +4989,11 @@ def run_gateway(verbose: int = 0, quiet: bool = False, replace: bool = False, fo _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", code=getattr(e, "code", None), traceback=_traceback.format_exc()) - if e.code is None: - _code = 0 - elif isinstance(e.code, int): - _code = e.code - else: - _code = 1 - _hard_exit_after_gateway_teardown(_code) + _exit_diag("asyncio.run.SystemExit", code=e.code, traceback=_traceback.format_exc()) + _hard_exit_after_gateway_teardown(0 if e.code is None else e.code if isinstance(e.code, int) else 1) except BaseException as e: # Everything else (CancelledError, exotic BaseExceptions): log the cause, then re-raise. - _exit_diag( - "asyncio.run.exception", - exc_type=type(e).__name__, - exc_repr=repr(e), - traceback=_traceback.format_exc(), - ) + _exit_diag("asyncio.run.exception", exc_type=type(e).__name__, exc_repr=repr(e), traceback=_traceback.format_exc()) raise if not success: _exit_diag("gateway.exit_nonzero")