[Haik]: ckpt, abstracted helpers within NineRouterProcess

This commit is contained in:
haikdc
2026-04-05 20:47:18 -07:00
parent aa250ce203
commit 28820c91eb
5 changed files with 67 additions and 49 deletions
@@ -9,31 +9,21 @@ import os
import shutil
import subprocess
import threading
from typing import Optional
import httpx
from typeguard import typechecked
from backend.ports import NINE_ROUTER_PORT
from backend.apps.subscriptions.NineRouter.constants import NINE_ROUTER_V1, NINE_ROUTER_URL
from backend.apps.subscriptions.NineRouter.NineRouterProcess.helpers.forward_output import forward_output
from backend.apps.subscriptions.NineRouter.NineRouterProcess.helpers.find_9router_dir import find_9router_dir
from backend.apps.subscriptions.NineRouter.NineRouterProcess.helpers.find_node import find_node
P_PROCESS: subprocess.Popen | None = None
P_THIS_DIR: str = os.path.dirname(os.path.abspath(__file__))
def _forward_output(pipe) -> None:
try:
for line in iter(pipe.readline, b""):
text = line.decode("utf-8", errors="replace").rstrip()
if text:
print(f"[9router] {text}", flush=True)
except Exception:
pass
finally:
try:
pipe.close()
except Exception:
pass
@typechecked
def is_running() -> bool:
@@ -44,37 +34,6 @@ def is_running() -> bool:
return False
@typechecked
def _find_9router_dir() -> str | None:
"""Locate the bundled 9Router directory (dev or packaged)."""
_is_packaged: bool = os.environ.get("OPENSWARM_PACKAGED") == "1"
if _is_packaged:
_resources: str = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(P_THIS_DIR))))
_candidate: str = os.path.join(_resources, "9router")
if os.path.isdir(_candidate):
return _candidate
else:
_backend_dir: str = os.path.dirname(os.path.dirname(os.path.dirname(P_THIS_DIR)))
_project_root: str = os.path.dirname(_backend_dir)
_candidate = os.path.join(_project_root, "9router")
if os.path.isdir(_candidate):
return _candidate
return None
@typechecked
def _find_node() -> str | None:
node: str | None = shutil.which("node")
if node:
return node
electron_path: str | None = os.environ.get("OPENSWARM_ELECTRON_PATH")
if electron_path and os.path.exists(electron_path):
return electron_path
return None
@typechecked
async def ensure_running() -> None:
"""Start 9Router if not already running."""
@@ -99,7 +58,7 @@ async def ensure_running() -> None:
else:
return
_9router_dir: str | None = _find_9router_dir()
_9router_dir: Optional[str] = find_9router_dir(P_THIS_DIR)
cmd: list[str]
cwd: str | None
env: dict[str, str]
@@ -112,7 +71,7 @@ async def ensure_running() -> None:
print("9Router: standalone build not found in", _9router_dir, flush=True)
return
node: str | None = _find_node()
node: Optional[str] = find_node()
if not node:
print("9Router: Node.js not found, cannot start in packaged mode", flush=True)
return
@@ -175,7 +134,7 @@ async def ensure_running() -> None:
stderr=subprocess.STDOUT,
env=env,
)
threading.Thread(target=_forward_output, args=(P_PROCESS.stdout,), daemon=True).start()
threading.Thread(target=forward_output, args=(P_PROCESS.stdout,), daemon=True).start()
timeout: int = 20 if _is_packaged else 30
for _ in range(timeout * 2):
@@ -0,0 +1,26 @@
import os
from typing import Optional
from typeguard import typechecked
# TODO: type spec this entirely
@typechecked
def find_9router_dir(
root_dir: str,
) -> Optional[str]:
"""Locate the bundled 9Router directory (dev or packaged)."""
p_is_packaged: bool = os.environ.get("OPENSWARM_PACKAGED") == "1"
if p_is_packaged:
p_resources: str = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(root_dir))))
p_candidate: str = os.path.join(p_resources, "9router")
if os.path.isdir(p_candidate):
return p_candidate
else:
p_backend_dir: str = os.path.dirname(os.path.dirname(os.path.dirname(root_dir)))
p_project_root: str = os.path.dirname(p_backend_dir)
p_candidate = os.path.join(p_project_root, "9router")
if os.path.isdir(p_candidate):
return p_candidate
return None
@@ -0,0 +1,15 @@
import os
import shutil
from typing import Optional
from typeguard import typechecked
@typechecked
def find_node() -> Optional[str]:
node: Optional[str] = shutil.which("node")
if node:
return node
electron_path: Optional[str] = os.environ.get("OPENSWARM_ELECTRON_PATH")
if electron_path and os.path.exists(electron_path):
return electron_path
return None
@@ -0,0 +1,18 @@
from typeguard import typechecked
# TODO: type spec this entirely
@typechecked
def forward_output(pipe) -> None:
try:
for line in iter(pipe.readline, b""):
text = line.decode("utf-8", errors="replace").rstrip()
if text:
print(f"[9router] {text}", flush=True)
except Exception:
pass
finally:
try:
pipe.close()
except Exception:
pass
+1 -1
View File
@@ -15,7 +15,7 @@ from fastapi import HTTPException, Request
from fastapi.responses import HTMLResponse, JSONResponse
from backend.config.Apps import SubApp
from backend.apps.subscriptions.NineRouter.NineRouterProcess import (
from backend.apps.subscriptions.NineRouter.NineRouterProcess.NineRouterProcess import (
is_running, ensure_running, stop,
)
from backend.apps.subscriptions.NineRouter.NineRouterClient import (