优化拔出逻辑
This commit is contained in:
@@ -97,15 +97,20 @@ class Deviceinfo(object):
|
||||
now_udids = {d.udid for d in lists if d.conn_type == ConnectionType.USB}
|
||||
|
||||
# 1. 失踪登记 & 累加
|
||||
need_remove = None # ← 新增:放锁外记录
|
||||
with self._lock:
|
||||
for udid in list(self._model_index.keys()):
|
||||
if udid not in now_udids:
|
||||
self._miss_count[udid] = self._miss_count.get(udid, 0) + 1
|
||||
if self._miss_count[udid] >= 3:
|
||||
self._remove_model(udid)
|
||||
self._miss_count.pop(udid, None)
|
||||
need_remove = udid # ← 只记录,不调用
|
||||
else:
|
||||
self._miss_count.pop(udid, None) # 设备又出现,清零
|
||||
self._miss_count.pop(udid, None)
|
||||
|
||||
# 🔓 锁已释放,再删设备(不会重入)
|
||||
if need_remove:
|
||||
self._remove_model(need_remove)
|
||||
|
||||
# 2. 全新插入(只处理未在线且信任且未满)
|
||||
for d in lists:
|
||||
@@ -114,13 +119,13 @@ class Deviceinfo(object):
|
||||
udid = d.udid
|
||||
with self._lock:
|
||||
if udid in self._model_index:
|
||||
continue # 已存在,跳过
|
||||
continue
|
||||
if not self.is_device_trusted(udid):
|
||||
continue
|
||||
if len(self.deviceModelList) >= self.maxDeviceCount:
|
||||
continue
|
||||
try:
|
||||
self.connectDevice(udid) # 内部会 _add_model
|
||||
self.connectDevice(udid)
|
||||
except Exception as e:
|
||||
LogManager.error(f"连接设备失败 {udid}: {e}", udid)
|
||||
|
||||
@@ -179,47 +184,63 @@ class Deviceinfo(object):
|
||||
|
||||
# 删除设备
|
||||
def _remove_model(self, udid: str):
|
||||
"""线程安全:把设备从内存、端口、iproxy 完全抹掉"""
|
||||
model = self._model_index.pop(udid, None)
|
||||
if not model:
|
||||
LogManager.error(f"没有找到需要删除的设备 {udid}")
|
||||
return
|
||||
model.type = 2
|
||||
print(f"【删】进入删除方法 udid={udid}")
|
||||
# 1. 纯内存临界区——毫秒级
|
||||
with self._lock:
|
||||
print(f"【删】拿到锁 udid={udid}")
|
||||
model = self._model_index.pop(udid, None)
|
||||
if not model:
|
||||
print(f"【删】模型已空,直接返回 udid={udid}")
|
||||
return
|
||||
if model.deleting:
|
||||
print(f"【删】正在删除中,幂等返回 udid={udid}")
|
||||
return
|
||||
model.deleting = True
|
||||
# 标记维删除设备
|
||||
model.type = 2
|
||||
print(f"【删】标记 deleting=True udid={udid}")
|
||||
|
||||
# 1. 内存列表删除
|
||||
try:
|
||||
self.deviceModelList.remove(model)
|
||||
except ValueError:
|
||||
pass
|
||||
# 过滤列表
|
||||
before = len(self.deviceModelList)
|
||||
self.deviceModelList = [m for m in self.deviceModelList if m.deviceId != udid]
|
||||
after = len(self.deviceModelList)
|
||||
print(f"【删】列表过滤 before={before} → after={after} udid={udid}")
|
||||
|
||||
# 2. 端口回收
|
||||
self._free_port(model.screenPort)
|
||||
# 端口
|
||||
self._port_in_use.discard(model.screenPort)
|
||||
self._port_pool.append(model.screenPort)
|
||||
print(f"【删】回收端口 port={model.screenPort} udid={udid}")
|
||||
|
||||
# 3. 原子化清理 iproxy(确保进程彻底死)
|
||||
to_kill, survivors = [], []
|
||||
for item in self.pidList:
|
||||
(to_kill if item.get("id") == udid else survivors).append(item)
|
||||
# 进程
|
||||
to_kill = [item for item in self.pidList if item.get("id") == udid]
|
||||
self.pidList = [item for item in self.pidList if item.get("id") != udid]
|
||||
print(f"【删】待杀进程数 count={len(to_kill)} udid={udid}")
|
||||
|
||||
for item in to_kill:
|
||||
self._terminate_proc(item.get("target")) # 下面也给了加强版实现
|
||||
# 2. IO 区无锁
|
||||
for idx, item in enumerate(to_kill, 1):
|
||||
print(f"【删】杀进程 {idx}/{len(to_kill)} pid={item.get('target').pid} udid={udid}")
|
||||
self._terminate_proc(item.get("target"))
|
||||
print(f"【删】进程清理完成 udid={udid}")
|
||||
|
||||
self.pidList = survivors
|
||||
LogManager.info(f"设备下线 {udid},当前在线数:{len(self.deviceModelList)}")
|
||||
|
||||
# 4. 发 Socket
|
||||
# 3. 网络 IO
|
||||
retry = 3
|
||||
while retry:
|
||||
try:
|
||||
self.manager.send(model.toDict())
|
||||
print(f"【删】下线事件已发送 udid={udid}")
|
||||
break
|
||||
except Exception as e:
|
||||
retry -= 1
|
||||
LogManager.error(f"发送下线事件失败,{udid} 剩余重试 {retry}:{e}")
|
||||
print(f"【删】发送事件失败 retry={retry} err={e} udid={udid}")
|
||||
time.sleep(0.2)
|
||||
else:
|
||||
LogManager.error(f"发送下线事件彻底失败,{udid} 主动崩溃防止状态不一致")
|
||||
print(f"【删】发送事件彻底失败,主动退出 udid={udid}")
|
||||
os._exit(1)
|
||||
|
||||
print(f"【删】===== 设备 {udid} 删除全流程结束 =====")
|
||||
print(len(self.deviceModelList))
|
||||
|
||||
|
||||
# region ===================== 端口分配与回收 =====================
|
||||
def _alloc_port(self) -> int:
|
||||
if self._port_pool:
|
||||
|
||||
Reference in New Issue
Block a user