fix: 设备异常状态清除(清除异常/一键清除,检查与更新原子化防竞态)

This commit is contained in:
2026-08-11 08:22:24 +08:00
parent 5f914c4fe4
commit 8a3cd67a97
4 changed files with 86 additions and 10 deletions
+31 -4
View File
@@ -28,12 +28,13 @@ from flask_login import (LoginManager, login_user, logout_user,
from core.stf_client import STFClient
from core.task_manager import TaskManager
from core.device_worker import get_all_worker_status
from core.device_worker import clear_worker_error, clear_all_worker_errors
from core.logger import get_logger, _LOG_DIR, _MODULE_FILES
from core.models import db, init_db, User, DeviceGroup, TaskJob, CustomAction
from core.apk_manager import ApkManager
from core.adb_helper import screenshot, list_installed_apps
from core.adb_helper import screenshot, list_installed_apps, adb_connect_light, _ADB_LOCK, _adb
from core import uiauto_helper
from config import ADB_PATH, STF_SSH_TARGET, STF_DOCKER_CONTAINER
from tasks import list_task_types, get_task_class
_log = get_logger("web")
@@ -439,19 +440,45 @@ def api_stop_device():
@app.route("/api/stop_all", methods=["POST"])
@login_required
@perm_required(PERM_DEVICES)
def api_stop_all():
stopped = mgr.stop_all()
return jsonify({"ok": True, "stopped": stopped})
@app.route("/api/release", methods=["POST"])
@login_required
@perm_required(PERM_DEVICES)
def api_release():
released, failed = stf.release_all_mine()
return jsonify({"ok": True, "released": released, "failed": failed})
@app.route("/api/device/clear_error", methods=["POST"])
@perm_required(PERM_DEVICES)
def api_device_clear_error():
"""清除单台设备的异常状态(error/failed → idle),供设备列表"清除异常"按钮使用。"""
serial = (request.json or {}).get("serial", "")
if not serial:
return jsonify({"ok": False, "error": "缺少 serial"}), 400
if serial in mgr.get_running():
return jsonify({"ok": False, "error": "设备正在运行或等待重试,无法清除"}), 400
if not clear_worker_error(serial):
return jsonify({"ok": False, "error": "设备正在运行任务,无法清除"}), 400
_log.info(f"清除设备 {serial} 的异常状态")
return jsonify({"ok": True, "msg": f"已清除 {serial} 的异常状态"})
@app.route("/api/device/clear_all_errors", methods=["POST"])
@perm_required(PERM_DEVICES)
def api_device_clear_all_errors():
"""一键清除所有异常/失败设备(跳过正在运行/等待重试的)。"""
running = set(mgr.get_running())
cleared = clear_all_worker_errors(exclude=running)
_log.info(f"一键清除异常:共清除 {cleared} 台")
return jsonify({"ok": True, "cleared": cleared,
"msg": f"已清除 {cleared} 台设备的异常状态"})
@app.route("/api/device/screenshot")
@login_required
def api_device_screenshot():