fix(sync): 限流退避持久化到 DB,调度器与手动同步均尊重退避期

db.py: 修复迁移非幂等——gunicorn 双 worker 并发 init_db 时后到者遇 Duplicate column 会让整个服务起不来,改为吞掉 duplicate column 错误。garmin.py/scheduler.py: 退避期写入 sync_status.rate_limited_until,自动同步与手动同步在退避期内跳过,不再反复撞击 Garmin 把限流窗口越撞越深。
This commit is contained in:
ericwyuan
2026-08-28 14:54:10 +08:00
parent a4bedc263f
commit 11869c6a8d
3 changed files with 125 additions and 8 deletions

View File

@@ -144,6 +144,16 @@ def sync_all_accounts(days=None, respect_schedule=False):
results.append({"user": uid, "status": "skipped",
"reason": "not due"})
continue
# Never poke Garmin while it is rate-limiting us — that is exactly
# what keeps the limit alive. Respect the persisted cooldown and sit
# this tick out.
blocked = garmin_svc.rate_limited_until(uid)
if blocked and blocked > _now():
results.append({
"user": uid, "status": "skipped", "reason": "rate-limited",
"retryAfterSeconds": int((blocked - _now()).total_seconds()),
})
continue
out = garmin_svc.sync_data(uid, {}, days=days)
results.append({"user": uid, "status": out.get("status"),
"records": out.get("recordsSynced")})