临时提交
This commit is contained in:
@@ -67,13 +67,6 @@ class ThreadManager:
|
||||
|
||||
@classmethod
|
||||
def batch_stop(cls, udids: List[str]) -> Tuple[int, List[str], str]:
|
||||
"""
|
||||
批量停止任务——瞬间下发停止信号,仍统计失败结果。
|
||||
返回格式与原接口 100% 兼容:
|
||||
(code, fail_list, msg)
|
||||
code=200 全部成功
|
||||
code=1001 部分/全部失败
|
||||
"""
|
||||
if not udids:
|
||||
return 200, [], "无设备需要停止"
|
||||
|
||||
@@ -83,48 +76,53 @@ class ThreadManager:
|
||||
with cls._lock:
|
||||
for udid in udids:
|
||||
task = cls._tasks.get(udid)
|
||||
if not task or not task.get("running"):
|
||||
# fail_list.append(f"设备{udid}停止失败:当前设备没有执行相关任务")
|
||||
continue
|
||||
task["event"].set() # 下发停止信号
|
||||
if task and task.get("running"):
|
||||
task["event"].set()
|
||||
|
||||
# ---------- 2. 并发等 0.2 s 收尾 ----------
|
||||
def _wait_and_clean(udid: str) -> Tuple[int, str]:
|
||||
with cls._lock:
|
||||
task = cls._tasks.get(udid)
|
||||
if not task:
|
||||
return 400, "任务记录已丢失"
|
||||
thread = task["thread"]
|
||||
# 第一次等 3 秒,让“分片睡眠”有机会退出
|
||||
thread.join(timeout=3)
|
||||
# 如果还活,再补 2 秒
|
||||
if thread.is_alive():
|
||||
thread.join(timeout=2)
|
||||
# 最终仍活,记录日志但不硬杀,避免僵尸
|
||||
with cls._lock:
|
||||
cls._tasks.pop(udid, None)
|
||||
if thread.is_alive():
|
||||
LogManager.warning(f"[batch_stop] 线程 5s 未退出,已清理记录但线程仍跑 {udid}")
|
||||
return 201, "已下发停止,线程超长任务未立即结束"
|
||||
return 200, "已停止"
|
||||
# ---------- 2. 单设备重试 5 次 ----------
|
||||
def _wait_and_clean_with_retry(udid: str) -> Tuple[int, List[str], str]:
|
||||
"""
|
||||
内部重试 5 次,最终返回格式与 batch_stop 完全一致:
|
||||
(code, fail_list, msg) fail_list 空表示成功
|
||||
"""
|
||||
for attempt in range(1, 6):
|
||||
with cls._lock:
|
||||
task = cls._tasks.get(udid)
|
||||
if not task:
|
||||
return 200, [], "任务已不存在" # 成功
|
||||
thread = task["thread"]
|
||||
|
||||
thread.join(timeout=5)
|
||||
still_alive = thread.is_alive()
|
||||
|
||||
# 最后一次重试才清理记录
|
||||
if attempt == 5:
|
||||
with cls._lock:
|
||||
cls._tasks.pop(udid, None)
|
||||
|
||||
if not still_alive:
|
||||
return 200, [], "已停止"
|
||||
|
||||
LogManager.warning(f"[batch_stop] {udid} 第{attempt}/5 次停止未立即结束,重试", udid)
|
||||
|
||||
# 5 次都失败
|
||||
LogManager.error(f"[batch_stop] {udid} 停止失败(5 次重试后线程仍活)", udid)
|
||||
return 1001, [udid], "部分设备停止失败"
|
||||
|
||||
# ---------- 3. 并发执行 ----------
|
||||
with ThreadPoolExecutor(max_workers=min(32, len(udids))) as executor:
|
||||
future_map = {executor.submit(_wait_and_clean, udid): udid for udid in udids}
|
||||
future_map = {executor.submit(_wait_and_clean_with_retry, udid): udid for udid in udids}
|
||||
for future in as_completed(future_map):
|
||||
udid = future_map[future]
|
||||
try:
|
||||
code, reason = future.result()
|
||||
if code != 200:
|
||||
fail_list.append(f"设备{udid}停止失败:{reason}")
|
||||
except Exception as exc:
|
||||
fail_list.append(f"设备{udid}停止异常:{exc}")
|
||||
code, sub_fail_list, sub_msg = future.result() # ← 现在解包正确
|
||||
if code != 200:
|
||||
fail_list.extend(sub_fail_list) # 收集失败 udid
|
||||
|
||||
# ---------- 3. 返回兼容格式 ----------
|
||||
# ---------- 4. 返回兼容格式 ----------
|
||||
if fail_list:
|
||||
return 1001, fail_list, "部分设备停止失败"
|
||||
return 200, [], "全部设备停止成功"
|
||||
|
||||
|
||||
@classmethod
|
||||
def is_task_running(cls, udid: str) -> bool:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user