From 29b4491afe6e88a34478b5272130a0bfc2476038 Mon Sep 17 00:00:00 2001 From: chengma Date: Mon, 10 Aug 2026 17:41:42 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=BD=92=E6=A1=A3=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?#109?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-量化领取到商品页耗时并消除重复设备检查.md | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 docs/task/109-量化领取到商品页耗时并消除重复设备检查.md diff --git a/docs/task/109-量化领取到商品页耗时并消除重复设备检查.md b/docs/task/109-量化领取到商品页耗时并消除重复设备检查.md new file mode 100644 index 0000000..65a5ce2 --- /dev/null +++ b/docs/task/109-量化领取到商品页耗时并消除重复设备检查.md @@ -0,0 +1,106 @@ +# 109 量化领取到商品页耗时并消除重复设备检查 + +- 类型:重构 +- 父级大工单:#1 +- 所属 MVP / 版本:MVP 后续 / 任务执行性能优化 +- 状态:已完成(待验收) +- 日期:2026-08-10 +- Gitea 工单: + +## 背景与目标 + +Client 领取任务后到 PDD 商品页通常需要十几秒,但原代码没有分阶段耗时,且设备 +连接已经读取一次 `app_current()` 后,采集和采购打开商品页又立即重复读取。 + +本任务建立不含业务数据的性能日志,量化 Admin、SQLite、ADB、uiautomator2 和 +商品页阶段,并在不降低安全校验的前提下去掉同一会话内的重复检查。 + +## 最终方案 + +- 新增轻量 `TaskPerformanceTrace`,使用单调时钟。任务调度器建立一次任务上下文, + 设备和页面适配层在同一工作线程取得该上下文,不跨任务共享。 +- 正式启动时把 JSONL 写入 `data/logs/task_performance.jsonl`,按 2 MiB 轮转并保留 + 3 个旧文件。字段白名单只有 `task_id`、`operation`、`duration_ms`、`result`。 +- 计时覆盖 ADB 检查、Admin 领取、本地保存、uiautomator2 连接、首次应用状态、 + PDD 启动/等待、打开链接、首次控件树、商品页就绪和端到端总耗时。 +- `PddDeviceSession` 保存连接时已经取得的应用状态。采集和采购打开商品页时复用该 + 瞬时结果,不再紧邻执行第二次 `app_current()`。 +- PDD 已由应用状态确认在前台时跳过固定 `app_wait()`;需要启动时仍启动并等待。 + 打开链接后仍重新读取应用、控件树和商品页,验证码、风控、登录及采购门禁不变。 +- 显式 ADB 检查当前每轮只有一次,因此保留并计时,没有删除新鲜连接校验。 +- 新增只读真机测量工具,分别执行冷/热启动。工具不点击规格、下单或付款,遇到 + 登录或安全验证会停止。 + +实现与建单方案一致。额外增加独立测量工具,用于重复取得同环境中位数和 P95; +没有修改线程架构、Admin 接口、数据库、任务状态或 `pdd_data`。 + +## 真机测量与结论 + +同一台 Wi-Fi ADB 设备、同一商品页各执行 5 次。单位为毫秒,中位数 / P95: + +| 阶段 | 冷启动 | 热启动 | +|---|---:|---:| +| ADB 设备检查 | 16 / 16 | 15 / 15 | +| `uiautomator2.connect()` | 234 / 297 | 203 / 250 | +| 首次 `app_current()` | 10593 / 10625 | 10578 / 10688 | +| PDD 启动或等待 | 1016 / 1172 | 906 / 969 | +| `open_url()` | 110 / 140 | 157 / 188 | +| 首次 `dump_hierarchy()` | 266 / 375 | 265 / 281 | +| 商品页就绪等待 | 2172 / 2281 | 2172 / 2266 | +| 端到端总耗时 | 14375 / 14516 | 14328 / 14422 | + +嵌套阶段不能直接相加:商品页就绪包含控件树读取,端到端又包含全部阶段。这台 +OPPO/ColorOS 即使 PDD 位于屏幕前台,`app_current()` 仍可能报告系统设置页, +所以热启动的启动/等待仍约 0.9 秒;控件树包名兜底继续保留。 + +原流程相邻调用两次 `app_current()`,本次按热启动中位数预计减少约 10.58 秒。 +优化后 `uiautomator2.connect()` 仅 203 毫秒,约占端到端 1.4%,未达到 #110 的 +2 秒或 20% 门槛。因此 #110 判定 No-Go,不实施持久 Device/QThread 重构。 + +## 改了哪些 + +- `client/src/performance_timing.py`:性能上下文、白名单记录和轮转日志。 +- `client/buyer_main.py`:正式启动时初始化性能日志。 +- `client/src/task_dispatcher.py`:记录 ADB、领取和本地保存,并绑定任务上下文。 +- `client/src/pdd_device_service.py`:区分连接和首次应用状态计时,保存瞬时结果。 +- `client/src/pdd_collect_service.py`:复用首次状态并记录采集商品页阶段。 +- `client/src/pdd_u2_purchase_adapter.py`:复用首次状态并记录采购商品页阶段。 +- `client/tools/measure_goods_open.py`:安全的冷/热启动真机测量工具。 +- `client/test/test_performance_timing.py`:验证单调计时、任务隔离和日志白名单。 +- 相关设备、采集、采购和调度测试:验证冷/热启动、去重及安全行为。 +- `docs/client/06-quality-security.md`:记录日志字段、阶段、嵌套含义和测量方法。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 每次正式任务记录规定阶段和端到端耗时 | 通过 | +| 单调时钟非负、任务隔离,嵌套差异有文档解释 | 通过 | +| 日志使用四字段白名单,不包含控件树、URL、异常正文或凭据 | 通过 | +| 复用首次应用状态,PDD 已在前台时跳过固定等待 | 通过 | +| 设备、页面、安全页和采购门禁保持有效 | 通过 | +| 同环境完成 5 次冷启动和 5 次热启动 | 通过 | +| #110 Go/No-Go 有数据依据 | 通过,No-Go | +| 专项、Client 全量测试和语法检查通过 | 通过 | +| 未启用真实下单,未执行下单或付款 | 通过 | + +## 测试 + +- 执行的命令: + - `C:/Python310/python.exe -m pytest test/test_performance_timing.py test/test_pdd_device_service.py test/test_pdd_collect_service.py test/test_pdd_u2_purchase_adapter.py test/test_task_dispatcher.py -q` + - `C:/Python310/python.exe -m pytest test -q` + - `C:/Python310/python.exe -m unittest discover -s test -p "test_*.py"` + - `C:/Python310/python.exe -m py_compile buyer_main.py src/performance_timing.py src/task_dispatcher.py src/pdd_device_service.py src/pdd_collect_service.py src/pdd_u2_purchase_adapter.py tools/measure_goods_open.py` + - `C:/Python310/python.exe tools/measure_goods_open.py <设备号> <商品链接> --runs 5` + - `git diff --check` +- 结果:专项测试 59 项通过;Client 全量 pytest 311 项通过;unittest 返回 `OK`; + 语法和差异检查通过;真机冷启动 5 次、热启动 5 次完成。 +- **没验证到的部分**:没有领取 10 条真实 Admin 任务,因此 Admin 请求和 SQLite + 保存的真机端到端日志由 Mock/临时 SQLite 自动化测试覆盖;没有在真机上主动触发 + 验证码、风控或登录失效,仅由既有单元测试和 XML 固件覆盖;离屏主窗口能够创建 + 并输出 `OK`,但立即关闭时出现既有在线更新 Worker 的迟到回调警告,本工单未修改 + 在线更新或窗口关闭流程。 + +## 相关提交 + +- `ba0706d` perf: 量化商品页打开耗时并去重检查 (#109)