fix(collect): handle login target close race
Tests / Python 3.11 / Windows (push) Has been cancelled
Tests / Python 3.11 / Windows (push) Has been cancelled
This commit is contained in:
+58
-4
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user