78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
"""
|
|
SDK 进程状态 — 正常态快照(供 connection_keeper / 负载均衡 / 控制台轮询)
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import time
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
from typing import Any, Dict, Optional
|
|
|
|
_PROCESS_STARTED_AT: float = time.time()
|
|
|
|
|
|
def mark_process_started() -> None:
|
|
"""lifespan 启动时调用,重置进程计时起点。"""
|
|
global _PROCESS_STARTED_AT
|
|
_PROCESS_STARTED_AT = time.time()
|
|
|
|
|
|
def _keeper_pid_file() -> Path:
|
|
sdk_app_root = Path(__file__).resolve().parent.parent
|
|
host_path = sdk_app_root.parent / "logs" / "connection_keeper.pid"
|
|
container_path = sdk_app_root / "logs" / "connection_keeper.pid"
|
|
for p in (host_path, container_path):
|
|
if p.is_file():
|
|
return p
|
|
# 宿主机 sdk/app 结构 vs Docker /app
|
|
if (sdk_app_root.parent / "scripts").is_dir():
|
|
return host_path
|
|
return container_path
|
|
|
|
|
|
def _read_keeper_state() -> Dict[str, Any]:
|
|
pid_file = _keeper_pid_file()
|
|
if not pid_file.is_file():
|
|
return {"running": False, "pid": None, "pid_file": str(pid_file)}
|
|
try:
|
|
pid = int(pid_file.read_text(encoding="utf-8").strip())
|
|
except (ValueError, OSError):
|
|
return {"running": False, "pid": None, "pid_file": str(pid_file)}
|
|
try:
|
|
os.kill(pid, 0)
|
|
return {"running": True, "pid": pid, "pid_file": str(pid_file)}
|
|
except OSError:
|
|
return {"running": False, "pid": pid, "pid_file": str(pid_file), "stale": True}
|
|
|
|
|
|
def get_process_status() -> Dict[str, Any]:
|
|
"""
|
|
返回 SDK 进程「正常态」快照。
|
|
state=normal 表示主进程存活且核心子系统可响应(与 /ready 语义对齐)。
|
|
"""
|
|
from services.ws_hub import ws_hub
|
|
|
|
uptime = max(0, int(time.time() - _PROCESS_STARTED_AT))
|
|
online_ids = list(ws_hub.connections.keys())
|
|
keeper = _read_keeper_state()
|
|
|
|
return {
|
|
"state": "normal",
|
|
"pid": os.getpid(),
|
|
"version": "3.0.0",
|
|
"started_at": datetime.fromtimestamp(_PROCESS_STARTED_AT, tz=timezone.utc).isoformat(),
|
|
"uptime_seconds": uptime,
|
|
"ready": True,
|
|
"ws_online_count": len(online_ids),
|
|
"online_device_ids": online_ids,
|
|
"connection_keeper": keeper,
|
|
"poll_urls": {
|
|
"process_status": "/api/v3/process/status",
|
|
"ready": "/ready",
|
|
"health": "/health",
|
|
"connection_status": "/api/v3/connection/status",
|
|
},
|
|
}
|