Cap export-task poll loops at 5min to avoid infinite hang

顺心/中通/韵达/安能 的导出任务轮询循环原本只在"本批任务全部完成"时
退出,无任何时间上限:任务卡在生成中、或因时钟偏移没落进 40s 容差窗口
匹配不上时,会无限轮询、流程永不返回,连 with_retry 都没机会触发。

给这 5 处轮询加 300s deadline,超时即 raise → 流程返回 False → 触发
已有的重置重试机制。把"永久挂死"变成"有界失败→自动重试"。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Misaka
2026-07-14 22:24:41 +08:00
parent 2d49c3d6f1
commit a71924ca1a
4 changed files with 38 additions and 0 deletions

View File

@@ -702,7 +702,14 @@ def poll_and_download_tasks(export_cdp, export_times, download_dir):
total_expected = len(export_times) total_expected = len(export_times)
print(f">> 轮询导出下载任务(期望 {total_expected} 个)...") print(f">> 轮询导出下载任务(期望 {total_expected} 个)...")
poll_deadline = (
time.monotonic() + 300
) # 5 分钟上限:任务卡死/匹配不上时超时失败,交由上层重置重试
while True: while True:
if time.monotonic() > poll_deadline:
raise RuntimeError(
"轮询导出任务超时5 分钟未全部完成/匹配),疑似任务卡死"
)
wait_until( wait_until(
export_cdp, export_cdp,
"!!document.querySelector('.ant-table-thead')", "!!document.querySelector('.ant-table-thead')",

View File

@@ -2,6 +2,7 @@
import os import os
import re import re
import time
import yaml import yaml
from datetime import datetime, timedelta from datetime import datetime, timedelta
import pandas as pd import pandas as pd
@@ -249,7 +250,14 @@ def shunxin_expected_download_impl(page):
# 7. 轮询任务状态 # 7. 轮询任务状态
print(">> 列表已加载,开始匹配并检查任务状态...") print(">> 列表已加载,开始匹配并检查任务状态...")
poll_deadline = (
time.monotonic() + 300
) # 5 分钟上限:任务卡死/匹配不上时超时失败,交由上层重置重试
while True: while True:
if time.monotonic() > poll_deadline:
raise RuntimeError(
"轮询导出任务超时5 分钟未全部完成/匹配),疑似任务卡死"
)
rows = page.locator(".ant-table-tbody > tr.ant-table-row") rows = page.locator(".ant-table-tbody > tr.ant-table-row")
row_count = rows.count() row_count = rows.count()
pending_tasks = 0 pending_tasks = 0
@@ -506,7 +514,14 @@ def shunxin_actual_download_impl(page):
# 6. 轮询任务状态 # 6. 轮询任务状态
print(">> 列表已加载,开始匹配并检查任务状态...") print(">> 列表已加载,开始匹配并检查任务状态...")
poll_deadline = (
time.monotonic() + 300
) # 5 分钟上限:任务卡死/匹配不上时超时失败,交由上层重置重试
while True: while True:
if time.monotonic() > poll_deadline:
raise RuntimeError(
"轮询导出任务超时5 分钟未全部完成/匹配),疑似任务卡死"
)
rows = page.locator(".ant-table-tbody > tr.ant-table-row") rows = page.locator(".ant-table-tbody > tr.ant-table-row")
row_count = rows.count() row_count = rows.count()
pending_tasks = 0 pending_tasks = 0

View File

@@ -2,6 +2,7 @@
import os import os
import re import re
import time
import yaml import yaml
from datetime import datetime, timedelta from datetime import datetime, timedelta
import pandas as pd import pandas as pd
@@ -602,7 +603,14 @@ def _yunda_poll_and_download_tasks(page, export_times, download_dir, final_filen
print(">> 开始轮询离线任务队列,直到全部完成...") print(">> 开始轮询离线任务队列,直到全部完成...")
total_expected = len(export_times) total_expected = len(export_times)
poll_deadline = (
time.monotonic() + 300
) # 5 分钟上限:任务卡死/匹配不上时超时失败,交由上层重置重试
while True: while True:
if time.monotonic() > poll_deadline:
raise RuntimeError(
"轮询导出任务超时5 分钟未全部完成/匹配),疑似任务卡死"
)
task_rows = export_ws_frame.locator( task_rows = export_ws_frame.locator(
".datagrid-view2 .datagrid-btable tbody tr.datagrid-row" ".datagrid-view2 .datagrid-btable tbody tr.datagrid-row"
) )

View File

@@ -2,6 +2,7 @@
import os import os
import re import re
import time
import yaml import yaml
from datetime import datetime from datetime import datetime
import pandas as pd import pandas as pd
@@ -496,7 +497,14 @@ def _zto_poll_and_download_tasks(page, export_times, download_dir, final_filenam
print(">> 列表已加载,开始匹配并检查任务状态...") print(">> 列表已加载,开始匹配并检查任务状态...")
total_expected = len(export_times) total_expected = len(export_times)
poll_deadline = (
time.monotonic() + 300
) # 5 分钟上限:任务卡死/匹配不上时超时失败,交由上层重置重试
while True: while True:
if time.monotonic() > poll_deadline:
raise RuntimeError(
"轮询导出任务超时5 分钟未全部完成/匹配),疑似任务卡死"
)
task_rows = taskdone_frame.locator( task_rows = taskdone_frame.locator(
"#taskdoneDatagrid .mini-grid-rows-view .mini-grid-row" "#taskdoneDatagrid .mini-grid-rows-view .mini-grid-row"
) )