Files
Neo-ZQYY/scripts/ops/resubmit_failed.py

170 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""重新提交上次执行中失败的 31 个任务。
先用 refresh_token 刷新 access_token再提交执行并轮询等待完成。
"""
from __future__ import annotations
import json
import sys
import time
from pathlib import Path
import requests
TOKEN_FILE = Path(__file__).parent / ".monitor_token"
BASE = "http://localhost:8000"
# refresh_token7 天有效)
REFRESH_TOKEN = (
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9."
"eyJzdWIiOiIxIiwic2l0ZV9pZCI6Mjc5MDY4NTQxNTQ0MzI2OSwidHlwZSI6InJlZnJlc2giLCJleHAiOjE3NzIyNjM0NjN9."
"XYoda5lfxNtTSAGWoLlYhS9cA-hTK9iqK0SqUyn2KV4"
)
def refresh_access_token() -> str:
"""用 refresh_token 换取新的 access_token。"""
resp = requests.post(
f"{BASE}/api/auth/refresh",
json={"refresh_token": REFRESH_TOKEN},
timeout=10,
)
if resp.status_code != 200:
print(f"❌ 刷新 token 失败: {resp.status_code} {resp.text}")
sys.exit(1)
data = resp.json()
token = data["access_token"]
# 缓存到文件
TOKEN_FILE.write_text(token, encoding="utf-8")
print(f"✅ access_token 已刷新并缓存")
return token
# ── 刷新 token ──
TOKEN = refresh_access_token()
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}
# 上次失败的 31 个任务
FAILED_TASKS = [
"DWS_ASSISTANT_DAILY",
"DWS_ASSISTANT_MONTHLY",
"DWS_ASSISTANT_CUSTOMER",
"DWS_ASSISTANT_SALARY",
"DWS_ASSISTANT_FINANCE",
"ODS_SETTLEMENT_RECORDS",
"ODS_PAYMENT",
"ODS_REFUND",
"DWS_BUILD_ORDER_SUMMARY",
"DWS_MEMBER_CONSUMPTION",
"DWS_MEMBER_VISIT",
"ODS_GOODS_CATEGORY",
"ODS_STORE_GOODS",
"ODS_STORE_GOODS_SALES",
"ODS_TENANT_GOODS",
"ODS_PLATFORM_COUPON",
"ODS_GROUP_PACKAGE",
"ODS_GROUP_BUY_REDEMPTION",
"ODS_INVENTORY_STOCK",
"ODS_INVENTORY_CHANGE",
"DWS_GOODS_STOCK_DAILY",
"DWS_GOODS_STOCK_WEEKLY",
"DWS_GOODS_STOCK_MONTHLY",
"DWS_FINANCE_DAILY",
"DWS_FINANCE_RECHARGE",
"DWS_FINANCE_INCOME_STRUCTURE",
"DWS_FINANCE_DISCOUNT_DETAIL",
"DWS_WINBACK_INDEX",
"DWS_NEWCONV_INDEX",
"DWS_RELATION_INDEX",
"DWD_LOAD_FROM_ODS",
]
config = {
"tasks": FAILED_TASKS,
"flow": "api_full",
"processing_mode": "full_window",
"window_mode": "custom",
"window_start": "2025-11-01",
"window_end": "2026-02-20",
"window_split": "month",
"window_split_days": 30,
"force_full": True,
"dry_run": False,
"lookback_hours": 24,
"overlap_seconds": 600,
}
print(f"📤 提交 {len(FAILED_TASKS)} 个失败任务重新执行...")
print(f" flow=api_full, mode=full_window, 2025-11-01~2026-02-20, 30天切分, force-full")
resp = requests.post(f"{BASE}/api/execution/run", headers=HEADERS, json=config, timeout=30)
if resp.status_code != 200:
print(f"❌ 提交失败: {resp.status_code} {resp.text}")
sys.exit(1)
data = resp.json()
execution_id = data["execution_id"]
print(f"✅ 已提交execution_id={execution_id}")
print(f" 轮询等待完成...")
poll_interval = 20
max_wait = 1800
elapsed = 0
while elapsed < max_wait:
time.sleep(poll_interval)
elapsed += poll_interval
mm, ss = divmod(elapsed, 60)
try:
hist_resp = requests.get(
f"{BASE}/api/execution/history?limit=5",
headers=HEADERS,
timeout=15,
)
if hist_resp.status_code == 401:
print(f" [{mm}m{ss}s] token 过期,刷新中...")
TOKEN = refresh_access_token()
HEADERS["Authorization"] = f"Bearer {TOKEN}"
continue
if hist_resp.status_code != 200:
print(f" [{mm}m{ss}s] 查询历史失败: {hist_resp.status_code}")
continue
history = hist_resp.json()
target = next((h for h in history if h["id"] == execution_id), None)
if target is None:
print(f" [{mm}m{ss}s] 执行记录尚未出现...")
continue
status = target.get("status", "unknown")
duration_ms = target.get("duration_ms")
duration_str = f"{duration_ms / 1000:.1f}s" if duration_ms else ""
if status in ("success", "failed", "cancelled"):
print(f"\n🏁 执行完成: status={status}, 耗时={duration_str}, exit_code={target.get('exit_code')}")
# 获取日志摘要
log_resp = requests.get(
f"{BASE}/api/execution/{execution_id}/logs",
headers=HEADERS,
timeout=30,
)
if log_resp.status_code == 200:
log_data = log_resp.json()
output = log_data.get("output_log", "") or ""
lines = output.strip().split("\n")
print(f"\n--- 日志末尾 60 行 ---")
for line in lines[-60:]:
print(line)
break
else:
print(f" [{mm}m{ss}s] status={status}")
except Exception as e:
print(f" [{mm}m{ss}s] 轮询异常: {e}")
else:
print(f"\n⏰ 超时({max_wait}s请手动检查 execution_id={execution_id}")