Skip to content

fix(mumu): 修复 MuMu 启动 -503 错误的重试处理 - #1981

Draft
anlan1027 wants to merge 1 commit into
AUTO-MAS-Project:devfrom
anlan1027:fix/mumu-startup-recovery
Draft

anlan1027 wants to merge 1 commit into
AUTO-MAS-Project:devfrom
anlan1027:fix/mumu-startup-recovery

Conversation

@anlan1027

@anlan1027 anlan1027 commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

摘要

  • MuMuManager 返回 -503 mainnx connect failed 时,原流程直接抛错;现在解析 JSON errcode,关联 Windows 退出码 4294966793 → -503,并保留未知错误的失败语义。
  • 对复查为离线的已知 -503 最多尝试三轮、间隔两秒,共享 MaxWaitTime;已在线或正在启动时不重复发送 launch,无法可信判断状态时停止恢复。
  • 按实际管理器路径和实例编号串行启停;修复等待锁超时的调用在收尾时可能关闭另一调用刚启动实例的竞态。恢复耗尽后记录账号失败并进入原有收尾,不再叠加 MAA/SRC/MaaEnd/BAAH/MaaFW 的任务重跑。
  • 安全恢复不执行涉及全部实例的启动前强力清理(即使既有选项开启也记录跳过原因),启动失败后的自动收尾不强制关闭归属未确认的实例;不删数据、不改系统权限、不重启 Windows。

测试与验证

  • 环境与提交:Linux 6.18、CPython 3.12.13、uv sync --locked --group dev;提交 7e1573925e64253aa81147b67ecdbcc2378e6e75,基于最新 dev ad3de270ef906019d863a09d399db5a667165b81。

  • 相关回归(提交后复跑):

    uv run --no-sync python -m pytest \
      tests/tools/test_mumu_launch_recovery.py \
      tests/task/test_mumu_startup_failure.py \
      tests/tools/test_mumu_foreground_budget.py \
      tests/utils/test_mumu_json_parse.py \
      tests/task/test_script_hard_timeout.py \
      tests/core/test_scheduler_ownership.py -q

    82 passed。覆盖正常/已运行/启动中、暂时及持续 -503、JSON 报错但退出码为 0、无符号退出码、命令报错但实例已启动、三轮及两秒间隔、共享超时、不同实例隔离、同实例并发、取消/超时释放锁、真实 MAA 入口停止外层重跑,以及调度终态、配置锁释放和后续脚本继续。

  • 全量:uv run --no-sync python -m pytest tests -q → 2066 passed, 4 failed, 43 skipped, 17 subtests passed。四项失败的基线对照见下文;没有新增失败,未删断言或增加 skip/xfail。

  • 额外最小核心回归:uv run --no-sync python -m pytest tests/task/test_maafw_core.py -q → 12 passed。

  • 静态检查:uv run --no-sync ruff format --check .、全部改动 Python 文件的 ruff check、uv lock --check、git diff --check、python scripts/changelog.py check --pr-base upstream/dev --pr-kind normal 均通过。mypy --config-file mypy-platform.ini --platform win32/linux/darwin 分别通过,均检查 23 个源文件。

  • 测试提交:新增 tests/tools/test_mumu_launch_recovery.py、tests/task/test_mumu_startup_failure.py;调整 tests/tools/test_mumu_foreground_budget.py 的真实初始化及状态夹具,保留原有前台检测预算断言。新增的等待锁超时场景在修正前实际尝试了 control -v 0 shutdown 而失败,修正后不关闭该实例并通过。

  • 版本记录:仅新增 changelog.d/mumu-launch-recovery.fix.md 一条碎片;res/version.json、项目版本号及已发布历史记录未改。

四项既有进程测试失败的复现与诊断

在隔离、未修改的最新 dev ad3de270ef906019d863a09d399db5a667165b81 上,运行以下同名用例,结果 4 failed(17.85 秒):

uv run --no-sync python -m pytest \
  'tests/platform/test_process_runner_env.py::test_stop_releases_pipes_inherited_by_a_background_service[False]' \
  'tests/platform/test_process_runner_env.py::test_stop_releases_pipes_inherited_by_a_background_service[True]' \
  'tests/platform/test_process_runner_env.py::test_deadline_reaps_wrapper_and_child_holding_pipes[False-False]' \
  'tests/platform/test_process_runner_env.py::test_deadline_reaps_wrapper_and_child_holding_pipes[True-False]' -q
用例 修复树全量结果 未修改 dev 对照
background_service[False] 测试 finally 的 service.wait(timeout=5) 抛 psutil.TimeoutExpired 相同错误
background_service[True] 同上 相同错误
wrapper_and_child[False-False] ProcessCleanupUnconfirmed: 无法确认子进程树已停止,不能释放更新目录 相同错误
wrapper_and_child[True-False] 同上 相同错误

只读检查这些测试自己记录的 PID:四个残留均为 status=zombie, ppid=1。前两项卡在测试清理等待,后两项的退出确认将未被容器 PID 1 回收的僵尸子进程保留为未确认状态;本次没有改动这些进程管理逻辑。

修复树与基线的以下文件逐字节相同:

  • app/utils/common/process/runner.py:SHA256 d32636941b37dcd062ffd48afff485bdfa8cffa831315fca225101400a07350c
  • tests/platform/test_process_runner_env.py:SHA256 dc6d4c6660f9d0fa73e630ea88679f0ed8eb0a238b16038e4960e936bdf25d56

没有修改生产代码、测试断言或 skip 来规避这些失败。CI 的 Windows/Ubuntu 结果需另行观察,不能由此推断一定通过。

已知限制与待验证范围

  • MuMu 内部 -503 根因未确认,云端没有真实 MuMu,真实故障未复现。Mock 证明的是 AUTO-MAS 对给定响应的识别、有限恢复和安全退出。
  • Windows 11 / MuMu / Android 15 实机验证未执行,因此保持 Draft。 本次不安装模拟器或连接用户电脑。后续可在本机确认路径/实例后验证;有已配置账号的作者也可按项目入口运行 cd frontend; yarn e2e:real,产出截图、HTML 报告和 real-e2e-summary.json,这条尚无实际执行证据。
  • MuMuManager 自身内部重试没有改动;三轮指 AUTO-MAS 发起的命令轮次,仍受总预算约束。持续失败、状态不可读及确认的低完整性标签等情况停止自动恢复、保留诊断,可能需要人工处理。
  • 实例锁只覆盖同一 AUTO-MAS 进程;外部程序不受锁约束,依靠每轮状态复查避免重复启动。失败后的部分启动实例可能保留运行,不做无法确认安全性的进程清理。
  • 遥测复用现有模拟器操作完成和任务结果观察入口,不新增事件或上传原始诊断信息。

CI(同一提交)

提交 7e1573925e64253aa81147b67ecdbcc2378e6e75 的 8 项 PR 检查均已完成并通过:

这不改变上面的本地容器四项既有失败记录,也不代表已完成 MuMu 实机验证;PR 保持 Draft,未合并。

@github-actions github-actions Bot added 模块: 模拟器 按更新日志碎片自动设置 类型: 修复 按更新日志碎片自动设置 labels Nov 13, 2026

Copy link
Copy Markdown
Contributor

总体结论:可以合并

宝宝,这版没有把 -503 变成无限重试,失败后也不会再让专项从头重跑,方向是对的喵。dot酱沿着 MuMu 启停、同实例并发和五个调用方的失败收尾查了一遍,静态审查未发现必须修改项。

恢复只在确认离线的已知错误上进行;启动中不重复 launch,取消继续向外传,任务失败记录和原有收尾仍保留。跳过启动前全局强杀、失败后保留归属不明的实例,是这里明确的安全取舍。

不过,这不等于真实 MuMu 的 -503 已修好啦:目前没有 Windows 11 / MuMu / Android 15 实机证据,dot酱也未运行项目代码或测试。实机验证仍按正文保留在 Draft 阶段;配置好模拟器和账号后,可从 frontend 运行 yarn e2e:real 核对真实入口,不能拿模拟响应替代。

—— 不乱重试,也不乱关实例的 dot酱 🐾

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

模块: 模拟器 按更新日志碎片自动设置 类型: 修复 按更新日志碎片自动设置

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants