perf: 量化商品页打开耗时并去重检查 (#109)

This commit is contained in:
chengma
2026-08-10 17:40:44 +08:00
parent 4c9bf3865b
commit ba0706dc47
13 changed files with 693 additions and 72 deletions
+55 -30
View File
@@ -9,6 +9,7 @@ from __future__ import annotations
import re
import time
import xml.etree.ElementTree as ET
from contextlib import nullcontext
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
from typing import Any, Callable, Mapping, Optional
from urllib.parse import parse_qs, urlparse
@@ -18,6 +19,7 @@ from .pdd_device_service import (
PddDeviceError,
PddDeviceService,
)
from .performance_timing import current_performance_trace
from .pdd_purchase_adapter import (
PddLivePurchaseAdapter,
PddPurchaseAdapter,
@@ -266,17 +268,24 @@ class U2PddPurchaseAdapter(PddPurchaseAdapter):
try:
self._session = self._device_service.connect(self._device_address)
self._device = self._session.__enter__()
current = self._device.app_current()
current = self._session.initial_app_state
trace = current_performance_trace()
if current.get("package") != PDD_PACKAGE_NAME:
self._device.app_start(PDD_PACKAGE_NAME)
if not self._device.app_wait(PDD_PACKAGE_NAME, timeout=10):
raise PddPurchaseError(
"DEVICE_APP_START_FAILED",
"PDD 应用启动失败",
step="purchase_open_goods",
retryable=True,
)
self._device.open_url(goods_url)
stage = trace.stage("pdd_start_or_wait") if trace else nullcontext()
with stage:
self._device.app_start(PDD_PACKAGE_NAME)
if not self._device.app_wait(PDD_PACKAGE_NAME, timeout=10):
raise PddPurchaseError(
"DEVICE_APP_START_FAILED",
"PDD 应用启动失败",
step="purchase_open_goods",
retryable=True,
)
elif trace is not None:
trace.record("pdd_start_or_wait", 0, "already_foreground")
stage = trace.stage("open_url") if trace else nullcontext()
with stage:
self._device.open_url(goods_url)
self._wait_for_page("goods", self._page_timeout)
except PddPurchaseError:
raise
@@ -436,26 +445,42 @@ class U2PddPurchaseAdapter(PddPurchaseAdapter):
session.__exit__(None, None, None)
def _wait_for_page(self, expected: str, timeout: float) -> str:
deadline = self._monotonic() + timeout
last_kind = "unknown"
while self._monotonic() < deadline:
self._check_cancelled("purchase_open_goods")
device = self._require_device()
current = device.app_current()
xml_data = self._dump_hierarchy()
root = _parse_xml(xml_data)
last_kind = _page_kind(root, str(current.get("package") or ""))
if last_kind == expected:
return xml_data
if last_kind in {"captcha", "login_required", "risk_control", "payment"}:
self._raise_special_page(last_kind)
self._sleep(0.25)
raise PddPurchaseError(
"PDD_PAGE_TIMEOUT",
f"等待 PDD {expected} 页面超时,最后页面为 {last_kind}",
step="purchase_open_goods",
retryable=True,
)
trace = current_performance_trace()
ready_stage = trace.stage("goods_page_ready") if trace else nullcontext()
with ready_stage:
deadline = self._monotonic() + timeout
last_kind = "unknown"
first_dump = True
while self._monotonic() < deadline:
self._check_cancelled("purchase_open_goods")
device = self._require_device()
current = device.app_current()
if first_dump and trace is not None:
with trace.stage("first_dump_hierarchy"):
xml_data = self._dump_hierarchy()
first_dump = False
else:
xml_data = self._dump_hierarchy()
root = _parse_xml(xml_data)
last_kind = _page_kind(root, str(current.get("package") or ""))
if last_kind == expected:
if trace is not None:
trace.checkpoint("end_to_end_total")
return xml_data
if last_kind in {
"captcha",
"login_required",
"risk_control",
"payment",
}:
self._raise_special_page(last_kind)
self._sleep(0.25)
raise PddPurchaseError(
"PDD_PAGE_TIMEOUT",
f"等待 PDD {expected} 页面超时,最后页面为 {last_kind}",
step="purchase_open_goods",
retryable=True,
)
def _wait_for_confirmation_panel(self) -> str:
deadline = self._monotonic() + self._panel_timeout