优化直播控制台:引入进程监控轻量轮询,并拆分 Live UI 组件

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
eric
2026-07-09 02:47:33 -05:00
parent 5f1b9db2dc
commit a0104f6517
16 changed files with 1969 additions and 461 deletions

View File

@@ -10,6 +10,7 @@ import os
import re
import shutil
import sys
import time
from pathlib import Path
from typing import Any, Callable, Optional
@@ -26,6 +27,37 @@ def strip_ansi_codes(text: str) -> str:
return re.sub(r"\x1b\[[0-9;]*m", "", text)
def _looks_like_null_device(path: str | Path | None) -> bool:
if not path:
return True
norm = str(path).replace("\\", "/").lower()
return "/dev/null" in norm or norm.endswith("/nul") or norm == "nul"
def _truncate_text_log(path: str | Path | None) -> None:
"""对齐 sh2每次 start 清空日志,避免旧 mtime 触发 stale/心跳过期。"""
if _looks_like_null_device(path):
return
log_path = Path(str(path))
try:
log_path.parent.mkdir(parents=True, exist_ok=True)
with log_path.open("w", encoding="utf-8", errors="ignore"):
pass
except OSError:
pass
def _child_env_for_process(process_name: str) -> dict[str, str]:
extra: dict[str, str] = {
"LIVE_PM2_PROCESS_NAME": process_name,
"PYTHONUNBUFFERED": "1",
"PYTHONIOENCODING": "utf-8",
}
if process_name.startswith("youtube2__"):
extra["RELAY_CHANNEL_ID"] = process_name[len("youtube2__") :]
return merge_child_env(extra)
class BuiltinSupervisor:
"""用本地 PID + 日志文件管理子进程,不依赖 Node/PM2。"""
@@ -107,11 +139,10 @@ class BuiltinSupervisor:
out_p, err_p = self._log_paths(process_name)
out_p.parent.mkdir(parents=True, exist_ok=True)
out_f = open(out_p, "ab")
err_f = open(err_p, "ab")
extra: dict[str, str] = {}
if process_name.startswith("youtube2__"):
extra["RELAY_CHANNEL_ID"] = process_name[len("youtube2__") :]
_truncate_text_log(out_p)
_truncate_text_log(err_p)
out_f = open(out_p, "a", encoding="utf-8", errors="ignore")
err_f = open(err_p, "a", encoding="utf-8", errors="ignore")
try:
proc = await asyncio.create_subprocess_exec(
*argv,
@@ -119,7 +150,7 @@ class BuiltinSupervisor:
stdout=out_f,
stderr=err_f,
creationflags=0,
env=merge_child_env(extra),
env=_child_env_for_process(process_name),
)
except Exception as e:
out_f.close()
@@ -134,6 +165,7 @@ class BuiltinSupervisor:
"script": script,
"out_log": str(out_p),
"err_log": str(err_p),
"started_at": time.strftime("%Y-%m-%dT%H:%M:%S"),
}
self._write_state(state)
return f"已启动 {script}PID {pid}),日志见 .pm2/logs"