fix(collect): handle login target close race
Tests / Python 3.11 / Windows (push) Has been cancelled

This commit is contained in:
chengma
2026-07-14 12:08:12 +08:00
parent cbfd36af56
commit f99cde8e05
11 changed files with 588 additions and 88 deletions
+58 -4
View File
@@ -1997,6 +1997,25 @@ class CollectWorker(BaseWorker):
},
on_step=on_step,
)
if result.get("close_target_confirmed") is False:
self._log_run_event(
"step=close_product result=uncertain detail=任务 {task_id} 商品 {item_id} 商品页已请求关闭,但未在短时间内确认关闭;采集结果已保留,继续处理后续任务".format(
task_id=task.id,
item_id=task.item_id,
),
task=task,
level="warning",
)
self._write_diagnostic_log(
"采集商品页关闭确认超时",
level="WARNING",
step="close_product",
task=task,
payload={
"alias": getattr(account, "alias", None),
"close_target_confirmed": False,
},
)
current_step = "db_write"
self._emit_activity(
"task_step",
@@ -2250,17 +2269,31 @@ class CollectWorker(BaseWorker):
}
def _confirmed_login_status(self, account, context, task=None):
started = time.monotonic()
subject = self._login_check_subject(account, task)
last_status = {}
for attempt in range(1, self.LOGIN_CHECK_ATTEMPTS + 1):
status = dict(self._login_status(account) or {})
status["login_check_attempts"] = attempt
last_status = status
if status.get("logged_in") or self._is_definitive_logged_out(status):
if status.get("logged_in"):
if attempt > 1:
self._log_run_event(
"step=login_check result=recovered detail={subject} 登录检测已恢复,第{attempt}/{total}次确认已登录 elapsed_ms={elapsed_ms}".format(
subject=subject,
attempt=attempt,
total=self.LOGIN_CHECK_ATTEMPTS,
elapsed_ms=self._elapsed_ms(started),
),
task=task,
)
return status
if self._is_definitive_logged_out(status):
return status
if attempt < self.LOGIN_CHECK_ATTEMPTS:
self._log_run_event(
"step=login_check result=retry detail=账号 {alias} 第{attempt}/{total}次登录检测暂不确定,{delay:g}秒后重试: {detail}".format(
alias=getattr(account, "alias", ""),
"step=login_check result=retry detail={subject} 登录状态暂时无法读取,第{attempt}/{total}次检测后将在{delay:g}秒后重试:{detail}".format(
subject=subject,
attempt=attempt,
total=self.LOGIN_CHECK_ATTEMPTS,
delay=self.LOGIN_CHECK_RETRY_DELAY_SECONDS,
@@ -2282,11 +2315,22 @@ class CollectWorker(BaseWorker):
"reason": last_status.get("reason"),
"url": last_status.get("url"),
"cookie_names": list(last_status.get("cookie_names") or []),
"cookie_read_succeeded": bool(
last_status.get("cookie_read_succeeded")
),
"probe_error": last_status.get("probe_error"),
"probe_attempts": last_status.get("probe_attempts"),
"attempts": last_status.get("login_check_attempts"),
},
)
return last_status
def _login_check_subject(self, account, task=None):
alias = str(getattr(account, "alias", "") or "未知账号")
if task is None:
return f"账号 {alias}"
return f"任务 {task.id} 商品 {task.item_id} 账号 {alias}"
def _is_definitive_logged_out(self, status):
reason = str((status or {}).get("reason") or "").strip()
url = str((status or {}).get("url") or "").lower()
@@ -2296,7 +2340,17 @@ class CollectWorker(BaseWorker):
def _login_status_detail(self, status):
status = status or {}
reason = status.get("reason") or "未知原因"
raw_reason = str(status.get("reason") or "").strip()
if raw_reason == "LOGIN_CHECK_TARGET_UNAVAILABLE":
reason = "CDP页面暂时不可用"
elif raw_reason.startswith("LOGIN_CHECK_FAILED"):
reason = "登录检测调用失败"
elif raw_reason == "NO_SESSION_COOKIE":
reason = "暂未读取到登录会话"
elif raw_reason == "LOGIN_PAGE":
reason = "检测到登录页面"
else:
reason = raw_reason or "未知原因"
url = status.get("url") or "未知URL"
cookie_names = [str(name) for name in (status.get("cookie_names") or []) if name]
cookie_text = ",".join(sorted(cookie_names)) if cookie_names else "未读到登录Cookie"