Don't apply the real-API daily budget / cooldown while bridging via Spotify Free
#798 follow-up. The Spotify enrichment worker's daily budget and post-ban cooldown both exist to protect the REAL authenticated API from bans. But the worker bridges to the no-creds Spotify Free source during a ban (a different, anonymous path), and those guards weren't free-aware: - the budget guard slept the worker when the daily cap was hit, blocking free work for no reason, - free-served items still incremented the budget counter, draining the real-API cap with calls that never touched the real API (so you'd return from a ban with budget already spent), and - the post-ban cooldown slept the worker even when serving via free. Fix: compute free_serving = client._free_active() once per loop (defensively wrapped → False on error → original behavior). When free_serving: - skip the daily-budget guard, - skip the post-ban-cooldown guard, - don't increment the daily budget. So the budget is now strictly a cap on REAL Spotify API usage; free runs unthrottled by it (the free client keeps its own inter-call pacing). The decision input (_free_active) is already pinned by the gate-model tests (free True exactly when rate-limited+Free / Free-primary, False when authed+healthy). Full suite clean (only pre-existing soundcloud /app env failures remain).
This commit is contained in:
parent
3fcfa900bd
commit
6b5506dee4
1 changed files with 20 additions and 5 deletions
|
|
@ -209,8 +209,19 @@ class SpotifyWorker:
|
|||
interruptible_sleep(self._stop_event, min(remaining, 60)) # Check again every 60s max
|
||||
continue
|
||||
|
||||
# Daily budget guard — worker-only cap to avoid saturating Spotify rate limits
|
||||
if self._is_daily_budget_exhausted():
|
||||
# Is the worker serving via the no-creds Spotify Free source this
|
||||
# iteration? The daily budget and post-ban cooldown both exist to
|
||||
# protect the REAL authenticated API from bans — they don't apply
|
||||
# to free (a different, anonymous path). Computed once and reused
|
||||
# below; the loop already probes auth, so no extra quota cost.
|
||||
try:
|
||||
free_serving = self.client._free_active()
|
||||
except Exception:
|
||||
free_serving = False
|
||||
|
||||
# Daily budget guard — worker-only cap to avoid saturating the REAL
|
||||
# Spotify API. Skipped while serving via free (free isn't that API).
|
||||
if not free_serving and self._is_daily_budget_exhausted():
|
||||
budget = self._get_daily_budget_info()
|
||||
resets_in = budget['resets_in_seconds']
|
||||
logger.info(f"Daily enrichment budget exhausted ({budget['used']}/{budget['limit']}), "
|
||||
|
|
@ -219,8 +230,9 @@ class SpotifyWorker:
|
|||
continue
|
||||
|
||||
# Post-ban cooldown guard — after ban expires, wait before resuming
|
||||
# to avoid immediately re-triggering the rate limit
|
||||
cooldown = self.client.get_post_ban_cooldown_remaining()
|
||||
# to avoid immediately re-triggering the rate limit. Only matters
|
||||
# for the real API, so skip it while serving via free.
|
||||
cooldown = 0 if free_serving else self.client.get_post_ban_cooldown_remaining()
|
||||
if cooldown > 0:
|
||||
logger.debug(f"Post-ban cooldown active ({cooldown}s left), sleeping...")
|
||||
interruptible_sleep(self._stop_event, min(cooldown, 60))
|
||||
|
|
@ -261,7 +273,10 @@ class SpotifyWorker:
|
|||
continue
|
||||
|
||||
self._process_item(item)
|
||||
self._increment_daily_budget()
|
||||
# Only real-API work counts toward the daily cap — free-served
|
||||
# items don't touch the authenticated API's quota.
|
||||
if not free_serving:
|
||||
self._increment_daily_budget()
|
||||
interruptible_sleep(self._stop_event, self.inter_item_sleep)
|
||||
|
||||
except SpotifyRateLimitError:
|
||||
|
|
|
|||
Loading…
Reference in a new issue