feat: 增加 systemd 定时执行与断点续跑
- backend/server.py: 信令 WebSocket 被远端关闭或视频流停滞超过阈值时自动拆除会话, 由 finally 释放网易云端实例,避免会话空挂、后续 /start 一直拿到 503 - bin/maa-online-daily-run: 新增日常任务包装脚本,等待 API 就绪、启动云游戏、 停滞看门狗(连续 ScreencapFailed 或 Disconnected)、失败即释放云会话并最多重试 3 次 - bin/maa-resume-tasks.py: 新增断点续跑规划器,重试时只运行未出现 Completed 的任务, 全部完成则直接判定成功,不再开启新会话;StartUp 永不跳过 - systemd/: 新增 server/daily/update 服务与定时器模板,每天 04:00 起随机 0-2 小时执行 - bin/maa-online-install-systemd: 渲染 __ROOT__ 并安装、启用上述单元 - README.md, user_config/README.md: 补充自动定时执行、断点续跑与已知限制说明 - .gitignore: 忽略生成的 config/tasks/daily-resume.toml
This commit is contained in:
+20
-2
@@ -35,6 +35,7 @@ WIDTH = int(os.getenv("MAA_ONLINE_WIDTH", "1280"))
|
||||
HEIGHT = int(os.getenv("MAA_ONLINE_HEIGHT", "720"))
|
||||
FPS = os.getenv("MAA_ONLINE_FPS", "30")
|
||||
START_WAIT_SECONDS = float(os.getenv("MAA_ONLINE_START_WAIT_SECONDS", "30"))
|
||||
STALE_LIMIT = float(os.getenv("MAA_ONLINE_STALE_LIMIT_SECONDS", "120"))
|
||||
|
||||
# --- 颜色定义 ---
|
||||
class Colors:
|
||||
@@ -439,9 +440,26 @@ async def run_cloud_game():
|
||||
raise RuntimeError("failed to receive the first cloud-game video frame")
|
||||
|
||||
# Use a cancellable wait instead of Event().wait()
|
||||
# This allows the task to be properly cancelled by signals
|
||||
# This allows the task to be properly cancelled by signals.
|
||||
# Also watch for a dead cloud session: if the remote signaling
|
||||
# websocket closes or the video stream stalls for too long, tear
|
||||
# the session down (finally-block releases the NetEase session and
|
||||
# closes the peer connection) so the next /start reconnects cleanly
|
||||
# instead of serving 503s forever.
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
await asyncio.sleep(5)
|
||||
sock = app_state.sock
|
||||
if sock is not None and sock.close_code is not None:
|
||||
raise RuntimeError(
|
||||
f"cloud signaling websocket closed (code {sock.close_code}); tearing down session"
|
||||
)
|
||||
snapshotter = app_state.snapshotter
|
||||
if snapshotter is not None:
|
||||
last_recv = getattr(snapshotter, "_last_recv_ts", 0.0)
|
||||
if last_recv and (time.monotonic() - last_recv) > STALE_LIMIT:
|
||||
raise RuntimeError(
|
||||
f"cloud video stream stale for over {STALE_LIMIT:.0f}s; tearing down session"
|
||||
)
|
||||
|
||||
except asyncio.CancelledError:
|
||||
print(f"\n{Colors.CYAN}[*] Cloud game task cancelled.{Colors.RESET}")
|
||||
|
||||
Reference in New Issue
Block a user