From c73df05fd92cc0ccc318fa6038db7b4417703061 Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Wed, 1 Apr 2026 08:55:38 -0700 Subject: [PATCH] Auto-pause rate-limited enrichment workers during downloads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spotify, Last.fm, and Genius enrichment workers are now automatically paused while any download batch is active. This prevents enrichment API calls from competing with post-processing metadata lookups for rate limit headroom, especially during heavy download scenarios (3 playlist workers + wishlist downloads simultaneously). Workers resume automatically when all downloads finish. Only workers that were auto-paused are resumed — manually paused workers stay paused. Piggybacks on the existing 2-second enrichment status loop with no new threads or timers. --- web_server.py | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/web_server.py b/web_server.py index d63f5ae5..76fb0044 100644 --- a/web_server.py +++ b/web_server.py @@ -47023,8 +47023,25 @@ def _emit_wishlist_count_loop(): # --- Phase 3: Enrichment sidebar worker emitters --- +def _has_active_downloads(): + """Check if any download batches are currently active.""" + try: + with tasks_lock: + for batch_data in download_batches.values(): + if batch_data.get('phase') not in ('complete', 'error', 'cancelled', None): + return True + except Exception: + pass + return False + + +# Track whether we auto-paused workers so we only resume ones we paused (not user-paused ones) +_download_auto_paused = set() + + def _emit_enrichment_status_loop(): - """Background thread that pushes all enrichment worker statuses every 2 seconds.""" + """Background thread that pushes all enrichment worker statuses every 2 seconds. + Also auto-pauses rate-limited enrichment workers during active downloads.""" workers = { 'musicbrainz': lambda: mb_worker, 'audiodb': lambda: audiodb_worker, @@ -47040,8 +47057,35 @@ def _emit_enrichment_status_loop(): 'listening-stats': lambda: listening_stats_worker, 'repair': lambda: repair_worker, } + + # Workers to auto-pause during downloads (rate-limit sensitive services) + yield_workers = { + 'spotify-enrichment': lambda: spotify_enrichment_worker, + 'lastfm-enrichment': lambda: lastfm_worker, + 'genius-enrichment': lambda: genius_worker, + } + while True: socketio.sleep(2) + + # Auto-pause/resume rate-limited workers during downloads + try: + downloading = _has_active_downloads() + for name, get_w in yield_workers.items(): + w = get_w() + if w is None: + continue + if downloading and not w.paused: + w.paused = True + _download_auto_paused.add(name) + logger.debug(f"Auto-paused {name} during active downloads") + elif not downloading and name in _download_auto_paused: + w.paused = False + _download_auto_paused.discard(name) + logger.debug(f"Auto-resumed {name} after downloads finished") + except Exception as e: + logger.debug(f"Error in download-yield check: {e}") + for name, get_worker in workers.items(): try: worker = get_worker()