fix(gateway): register foreground instances
This commit is contained in:
@@ -387,19 +387,27 @@ def _run_gateway(
|
||||
raise typer.Exit(1) from exc
|
||||
session_manager = SessionManager(config.workspace_path)
|
||||
|
||||
# Self-heal the gateway state file with the current PID after any restart.
|
||||
# Use the same runtime identity for foreground and managed gateway processes.
|
||||
from nanobot.config.loader import get_config_path
|
||||
from nanobot.gateway.runtime import GatewayRuntime, GatewayRuntimePaths
|
||||
from nanobot.gateway.runtime import GatewayRuntime, GatewayRuntimePaths, GatewayStartOptions
|
||||
|
||||
config_path = str(get_config_path().resolve(strict=False))
|
||||
GatewayRuntime.refresh_state_pid(
|
||||
gateway_workspace = (
|
||||
str(config.workspace_path)
|
||||
if not is_default_workspace(config.workspace_path)
|
||||
else None
|
||||
)
|
||||
gateway_runtime = GatewayRuntime(
|
||||
paths=GatewayRuntimePaths.for_instance(
|
||||
workspace=str(config.workspace_path)
|
||||
if not is_default_workspace(config.workspace_path)
|
||||
else None,
|
||||
workspace=gateway_workspace,
|
||||
config_path=config_path,
|
||||
)
|
||||
)
|
||||
gateway_start_options = GatewayStartOptions(
|
||||
port=port,
|
||||
workspace=gateway_workspace,
|
||||
config_path=config_path,
|
||||
)
|
||||
|
||||
# Preserve existing single-workspace installs, but keep custom workspaces clean.
|
||||
if is_default_workspace(config.workspace_path):
|
||||
@@ -946,4 +954,8 @@ def _run_gateway(
|
||||
finally:
|
||||
restore_shutdown_handlers()
|
||||
|
||||
asyncio.run(run())
|
||||
gateway_runtime.claim_current_process(gateway_start_options)
|
||||
try:
|
||||
asyncio.run(run())
|
||||
finally:
|
||||
gateway_runtime.release_current_process()
|
||||
|
||||
@@ -11,6 +11,7 @@ import time
|
||||
import uuid
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any, cast
|
||||
|
||||
@@ -102,6 +103,33 @@ class GatewayRuntime(ManagedProcessRuntime[ProcessStartOptions]):
|
||||
def _build_child_command(self, options: ProcessStartOptions) -> list[str]:
|
||||
return build_gateway_command(self.python_executable, options)
|
||||
|
||||
def claim_current_process(self, options: ProcessStartOptions) -> None:
|
||||
"""Publish the running foreground gateway for local client discovery."""
|
||||
with self._lifecycle_lock():
|
||||
state = self._read_state() or {}
|
||||
pid = os.getpid()
|
||||
state.update(
|
||||
{
|
||||
"pid": pid,
|
||||
"identity": self._process_identity(pid),
|
||||
"started_at": datetime.now(UTC).isoformat(),
|
||||
"platform": self.platform_name,
|
||||
"port": options.port,
|
||||
"workspace": options.workspace,
|
||||
"config_path": options.config_path,
|
||||
"command": self._build_child_command(options),
|
||||
"log_path": str(self.paths.log_path),
|
||||
}
|
||||
)
|
||||
self._write_state(state)
|
||||
|
||||
def release_current_process(self) -> None:
|
||||
"""Remove this foreground gateway's state without touching a replacement."""
|
||||
with self._lifecycle_lock():
|
||||
state = self._read_state()
|
||||
if state and self._record_matches_process(state, os.getpid()):
|
||||
self._clear_state()
|
||||
|
||||
def restart(self, options: ProcessStartOptions, *, timeout_s: int = 20) -> ProcessResult:
|
||||
"""Restart an existing gateway without creating a new persistent instance."""
|
||||
with self._lifecycle_lock():
|
||||
|
||||
Reference in New Issue
Block a user