From 02016b7b85443c61143ee5cba6a37af422cda66c Mon Sep 17 00:00:00 2001 From: butubb <1422726308@qq.com> Date: Sat, 8 Aug 2026 21:31:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=82=AC=E7=A9=BA=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E8=87=AA=E6=84=88=20-=20=E5=90=AF=E5=8A=A8=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8A=E6=94=BE=E6=AE=8B=E7=95=99=20STF=20?= =?UTF-8?q?=E5=8D=A0=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 崩溃/强杀后设备残留占用需手动清理。新增 AUTO_RELEASE_STALE_OCCUPY 配置 (默认关):单实例部署设为 true 时,web_server 启动自动释放本账户残留占用; 多实例共用 STF 账户时勿开(会误放另一实例任务)。默认仅启动提示。 --- config.py | 5 +++++ doc/DEPLOY.md | 4 +++- web_server.py | 16 +++++++++++----- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/config.py b/config.py index b3be224..880f243 100644 --- a/config.py +++ b/config.py @@ -59,3 +59,8 @@ DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data") # APK 文件存储目录(应用管理功能) APK_DIR = os.path.join(DATA_DIR, "apks") + +# ================== 悬空设备自愈 ================== +# 启动时是否自动释放"仍被本账户占用"的设备(上次崩溃/强杀残留)。 +# 仅单实例部署时设为 True:多实例共用同一 STF 账户时不要开,会误释放另一实例的运行中任务。 +AUTO_RELEASE_STALE_OCCUPY = _env("AUTO_RELEASE_STALE_OCCUPY", "false").lower() in ("1", "true", "yes") diff --git a/doc/DEPLOY.md b/doc/DEPLOY.md index 966dfed..65c226c 100644 --- a/doc/DEPLOY.md +++ b/doc/DEPLOY.md @@ -158,7 +158,9 @@ WantedBy=multi-user.target PYTHON=./.venv/bin/python bash scripts/supervise.sh ``` -> 进程守护只保证服务重启,不恢复已运行的任务(worker 状态在内存)。崩溃后残留的设备占用需用"强制释放占用"清理(或启动时的提示)。 +> 进程守护只保证服务重启,不恢复已运行的任务(worker 状态在内存)。 +> +> **悬空设备自愈**:崩溃后残留的设备占用(STF 仍显示占用)可配置启动自动清理。单实例部署时在 `.env` 设置 `AUTO_RELEASE_STALE_OCCUPY=true`,web_server 启动会自动释放本账户残留占用;**多实例共用 STF 账户时不要开**(会误放另一实例的任务)。默认关,仅启动时提示。 **Docker(生产 python-app 容器)**: diff --git a/web_server.py b/web_server.py index 045e40a..0390012 100644 --- a/web_server.py +++ b/web_server.py @@ -729,17 +729,23 @@ def _run_server(host, port): if __name__ == "__main__": - from config import WEB_HOST, WEB_PORT + from config import WEB_HOST, WEB_PORT, AUTO_RELEASE_STALE_OCCUPY # 自动启动 uiautodev 服务(元素抓取功能依赖,端口 20242) _ensure_uiauto_running() - # 启动时提示可能残留的 STF 占用(上次异常退出/强杀遗留)。 - # 不自动释放:本机与生产可能是多实例共用一个 STF 账户,误放会中断另一实例的任务。 + # 启动时处理可能残留的 STF 占用(上次异常退出/强杀遗留)。 + # AUTO_RELEASE_STALE_OCCUPY=True(单实例)时自动释放;否则仅提示。 + # 多实例共用一个 STF 账户时不要开启,误放会中断另一实例的任务。 try: _mine = stf.list_my_devices() if _mine: _serials = ", ".join(d["serial"] for d in _mine) - _log.warning(f"启动时发现 {len(_mine)} 台设备仍被本账户占用(可能异常退出残留):{_serials}。" - f"确认无其他实例在跑时可用\"强制释放占用\"清理") + if AUTO_RELEASE_STALE_OCCUPY: + _log.warning(f"启动时发现 {len(_mine)} 台设备残留占用,自动释放(AUTO_RELEASE_STALE_OCCUPY=True):{_serials}") + _released, _failed = stf.release_all_mine() + _log.info(f"自动释放完成:成功 {len(_released)} 台,失败 {len(_failed)} 台") + else: + _log.warning(f"启动时发现 {len(_mine)} 台设备仍被本账户占用(可能异常退出残留):{_serials}。" + f"单实例无人值守可设 AUTO_RELEASE_STALE_OCCUPY=True 自动清理") except Exception: pass _log.info(f"管理后台: http://localhost:{WEB_PORT}/ (admin/admin123)")