Files
workphone-sdk/sdk/app/services/process_state.py

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",
},
}