Merge pull request #425 from Nezreka/fix/spotify-worker-respect-primary-source

fix: pause Spotify worker on non-Spotify primary + cut daily budget t…
This commit is contained in:
BoulderBadgeDad 2026-04-29 13:18:26 -07:00 committed by GitHub
commit f4e6b49a35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 25 additions and 5 deletions

View file

@ -55,8 +55,13 @@ class SpotifyWorker:
self.inter_item_sleep = 1.5 # Between top-level items (each can trigger 5+ paginated calls)
self.batch_inter_item_sleep = 0.1 # Between local matches within a batch (no API calls)
# Daily budget — caps how many items this worker processes per calendar day
self.daily_budget = 3000
# Daily budget — caps how many items this worker processes per calendar day.
# Lowered from 3000 to 500 after Spotify's February 2026 API tightening
# (/v1/search max limit cut from 50 to 10) increased the per-track API call
# cost. Sustained 3000-item runs were tripping Spotify's automated abuse
# detection and earning multi-hour 429 bans. 500/day keeps the worker
# productive without crossing the threshold.
self.daily_budget = 500
self._daily_items_processed = 0
self._daily_date = date.today()

View file

@ -37103,18 +37103,33 @@ def deezer_resume():
# ================================================================================================
# --- Spotify Worker Initialization ---
# The Spotify enrichment worker calls `/v1/search` continuously to match library
# tracks against Spotify's catalog. After Spotify's February 2026 API tightening
# (search limit cut from 50→10, sustained-rate detection more aggressive), running
# this worker when the user has chosen a non-Spotify primary metadata source
# (Deezer, iTunes, Discogs, Hydrabase) generates dead API traffic that triggers
# multi-hour 429 bans and disrupts the user's actual selected source.
#
# Gate the worker at boot: only auto-start when Spotify is the configured primary
# source. Users on other sources can manually unpause the worker from settings if
# they explicitly want background Spotify enrichment.
spotify_enrichment_worker = None
try:
from core.metadata_service import get_primary_source as _get_primary_source
from database.music_database import MusicDatabase
spotify_enrichment_db = MusicDatabase()
spotify_enrichment_worker = SpotifyWorker(database=spotify_enrichment_db)
if config_manager.get('spotify_enrichment_paused', False):
_primary = _get_primary_source()
_user_paused = config_manager.get('spotify_enrichment_paused', False)
if _user_paused or _primary != 'spotify':
spotify_enrichment_worker.paused = True # Set BEFORE start() to prevent race condition
spotify_enrichment_worker.start()
if spotify_enrichment_worker.paused:
if not spotify_enrichment_worker.paused:
logger.info("Spotify enrichment worker initialized and started")
elif _user_paused:
logger.info("Spotify enrichment worker initialized (paused — restored from config)")
else:
logger.info("Spotify enrichment worker initialized and started")
logger.info(f"Spotify enrichment worker initialized (paused — primary metadata source is '{_primary}', not Spotify)")
except Exception as e:
logger.error(f"Spotify enrichment worker initialization failed: {e}")
spotify_enrichment_worker = None