阶段1: 调度/生命周期切换 device_pool——task_manager 设备解析与状态查询、STFDevice 去 occupy/release、web_server 端点换数据源(USB 桥接保留到阶段 2)

This commit is contained in:
2026-08-17 11:16:13 +08:00
parent 52c4d3aab4
commit 5354fe6379
5 changed files with 117 additions and 200 deletions
+14 -24
View File
@@ -18,6 +18,7 @@ import uiautomator2 as u2
from core.logger import get_logger
from core.stf_client import DeviceOfflineError, STFError
from core import device_pool
from .adb_helper import adb_connect, adb_disconnect
_log = get_logger("core.worker")
@@ -32,13 +33,15 @@ _U2_INFO_TIMEOUT = 10
class STFDevice:
"""单设备生命周期:acquire(占用+连接)→ release(断开+释放)。
"""单设备生命周期:acquire(直连)→ release(无操作)。
用 try/finally 保证设备一定被释放,即使养号中途报错。
阶段 1:已摘除 STF occupy/release——单实例互斥由 TaskManager._running 保证,
设备健康由 device_pool(本地 adb 在线状态)判断。保留 STF 引用仅为
非 IP:port(USB 序列号)设备的 remoteConnect 桥接,阶段 2 换成 220 adb server。
"""
def __init__(self, stf_client, serial=None):
self.stf = stf_client
def __init__(self, stf_client=None, serial=None):
self.stf = stf_client # 仅 USB 桥接用(阶段 2 移除)
self.serial = serial
self.remote_adb_url = None
@@ -46,22 +49,15 @@ class STFDevice:
self.serial = serial or self.serial or self._pick_free()
_log.info(f"[{self.serial}] 选定设备")
ok, msg = self.stf.occupy(self.serial)
if not ok:
raise STFError(f"占用设备失败: {msg}", "conflict")
_log.info(f"[{self.serial}] STF 占用成功")
# 直连优先:serial 本身是 IP:5555(如 Tailscale 网络设备)时直接 adb connect。
# 实测(本机 100.100.10.2,设备 100.100.10.x):
# - 本机在 tailnet 内时直连可靠且快(<1s),且只 connect、绝不 disconnect/kill-server,
# 不会影响 STF provider 共享的 adb 连接(STF 端设备保持 present/ready)。
# - STF remoteConnect 桥接在此环境反而有 adb key 认证问题(隧道显示 unauthorized,
# 即使设备已授权本机 key),直连才是可靠路径。
# 仅当 serial 不是 IP:port(如 USB 序列号)时才走 STF 桥接。
# 只 connect、绝不 disconnect/kill-server(红线),不影响 STF provider 的连接。
# 仅当 serial 不是 IP:port(如 USB 序列号)时才走 STF 桥接(阶段 2 替换)。
if ":" in self.serial:
self.remote_adb_url = self.serial
_log.info(f"[{self.serial}] 直连设备: {self.remote_adb_url}")
else:
if self.stf is None:
raise STFError(f"USB 设备 {self.serial} 暂不支持(未启用 STF 桥接)", "offline")
self.remote_adb_url = self.stf.remote_connect(self.serial)
_log.info(f"[{self.serial}] STF 桥接: {self.remote_adb_url}")
@@ -70,27 +66,21 @@ class STFDevice:
time.sleep(2)
def _pick_free(self):
free = self.stf.list_free_devices()
free = device_pool.list_ready()
if not free:
raise STFError("没有可用的在线空闲设备", "offline")
return free[0]["serial"]
return free[0]
def release(self):
if not self.serial:
return
# 直连模式(remote_adb_url == serial):不 disconnect
# STF provider 共享该 IP:5555 的 adb transport,disconnect 会让 STF 误判离线并重连
# 直连模式(remote_adb_url == serial):不 disconnect(红线,STF 共享 transport)
if self.remote_adb_url and self.remote_adb_url != self.serial:
adb_disconnect(self.remote_adb_url)
try:
self.stf.remote_disconnect(self.serial)
except Exception:
pass
ok, msg = self.stf.release(self.serial)
if ok:
_log.info(f"[{self.serial}] 已释放")
else:
_log.warning(f"[{self.serial}] STF 释放失败: {msg}")
# ================== 全局 worker 状态注册表(供 web_server 读取) ==================