From 8feb38db37558b3f166d0ffd481cac7c87ff9782 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 11 Aug 2026 03:39:57 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=B5=84=E6=BA=90=E5=8C=85=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=BF=AE=E5=A4=8D=E7=BF=BB=E9=A1=B5=E6=AD=BB=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E5=B9=B6=E5=8A=A0=20Status=20=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - debug_volc_sync.py 缺少 seen_tokens 防循环保护,火山 API 翻页到头后 NextToken 循环回起始 token,导致无限翻页(实测 900s 拉 1893 页假象, 真实数据仅 8 页 137 个包) - 两个 fetch_all_packages 请求加 Status=Effective,服务端直接过滤 UsedUp/Expired/Refunded 等余额为 0 的无用包(实测过滤后 0 余额包为 0) - 主脚本循环检测日志从 DEBUG 提升为 WARNING,循环收尾不再静默 --- debug_volc_sync.py | 16 +++++++++++++++- volc_limit_sync.py | 15 +++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/debug_volc_sync.py b/debug_volc_sync.py index fa76a15..93488dd 100644 --- a/debug_volc_sync.py +++ b/debug_volc_sync.py @@ -116,12 +116,15 @@ def fetch_all_packages(): version = "2022-01-01" all_packages = [] current_token = "" + seen_tokens = set() while True: try: payload = { "ResourceType": "Package", "MaxResults": "20", + # 只拉生效中的数据包,跳过 UsedUp/Expired/Refunded 等余额为 0 的无用包 + "Status": "Effective", "NextToken": current_token, } headers, body = get_signed_headers(action, version, payload) @@ -134,8 +137,19 @@ def fetch_all_packages(): if items: all_packages.extend(items) next_token = data.get("Result", {}).get("NextToken", "") - if not next_token or next_token == current_token: + + # Infinite Loop Protection: VolcEngine API 翻页到头后 NextToken 会 + # 循环回起始 token(实测:数据只有 ~8 页,第 9 页绕回第一个 token), + # 没有该保护会无限翻页。 + if not next_token: break + if next_token == current_token: + break + if next_token in seen_tokens: + print(f"WARNING: Detected pagination cycle with token {next_token}. Stopping.") + break + + seen_tokens.add(next_token) current_token = next_token time.sleep(0.2) except Exception as e: diff --git a/volc_limit_sync.py b/volc_limit_sync.py index 6171e15..3d0a2f2 100644 --- a/volc_limit_sync.py +++ b/volc_limit_sync.py @@ -863,6 +863,10 @@ def fetch_all_packages(): payload = { "ResourceType": "Package", "MaxResults": "20", + # 服务端只返回生效中的数据包,跳过 UsedUp/Expired/Refunded 等 + # 余额为 0 的无用包,显著减少翻页次数与 QPS 占用。 + # 周期型包(月度重置)状态仍为 Effective,不会被误过滤。 + "Status": "Effective", "NextToken": current_token, } headers, body = get_signed_headers(action, version, payload) @@ -876,15 +880,18 @@ def fetch_all_packages(): next_token = data.get("Result", {}).get("NextToken", "") # Infinite Loop Protection + # 火山 API 翻页到头后 NextToken 会循环回起始 token(实测数据只有 + # ~8 页时第 9 页绕回第一个 token),必须用 seen_tokens 拦下载断。 if not next_token: break if next_token == current_token: break if next_token in seen_tokens: - if DEBUG_MODE: - print( - f"DEBUG: Detected pagination cycle with token {next_token}. Stopping." - ) + log( + f"⚠️ VolcEngine pagination cycle detected (token {next_token} repeated). " + f"Stopping after {len(all_packages)} packages.", + level="WARNING", + ) break seen_tokens.add(next_token)