Pause enrichment workers during discovery to prioritize user-initiated API calls
This commit is contained in:
parent
1b42b88c31
commit
16e01f6039
1 changed files with 65 additions and 32 deletions
|
|
@ -22253,10 +22253,51 @@ def update_tidal_playlist_phase(playlist_id):
|
|||
|
||||
_playlist_discovery_cancelled = set() # Set of automation_ids that have been cancelled
|
||||
|
||||
def _pause_enrichment_workers(label='discovery'):
|
||||
"""Pause enrichment workers during discovery to reduce API contention.
|
||||
Returns tuple of (spotify_was_running, itunes_was_running) for resume."""
|
||||
s_was = False
|
||||
i_was = False
|
||||
try:
|
||||
if spotify_enrichment_worker and not spotify_enrichment_worker.paused:
|
||||
spotify_enrichment_worker.pause()
|
||||
s_was = True
|
||||
print(f"⏸️ Paused Spotify enrichment worker during {label}")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
if itunes_enrichment_worker and not itunes_enrichment_worker.paused:
|
||||
itunes_enrichment_worker.pause()
|
||||
i_was = True
|
||||
print(f"⏸️ Paused iTunes enrichment worker during {label}")
|
||||
except Exception:
|
||||
pass
|
||||
return s_was, i_was
|
||||
|
||||
|
||||
def _resume_enrichment_workers(was_running, label='discovery'):
|
||||
"""Resume enrichment workers that were paused by _pause_enrichment_workers."""
|
||||
s_was, i_was = was_running
|
||||
try:
|
||||
if s_was and spotify_enrichment_worker:
|
||||
spotify_enrichment_worker.resume()
|
||||
print(f"▶️ Resumed Spotify enrichment worker after {label}")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
if i_was and itunes_enrichment_worker:
|
||||
itunes_enrichment_worker.resume()
|
||||
print(f"▶️ Resumed iTunes enrichment worker after {label}")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def _run_playlist_discovery_worker(playlists, automation_id=None):
|
||||
"""Background worker that discovers Spotify/iTunes metadata for undiscovered
|
||||
mirrored playlist tracks. Stores results in extra_data for use by sync."""
|
||||
_ew_state = (False, False)
|
||||
try:
|
||||
_ew_state = _pause_enrichment_workers('mirrored playlist discovery')
|
||||
use_spotify = spotify_client and spotify_client.is_spotify_authenticated()
|
||||
discovery_source = 'spotify' if use_spotify else 'itunes'
|
||||
|
||||
|
|
@ -22512,6 +22553,8 @@ def _run_playlist_discovery_worker(playlists, automation_id=None):
|
|||
_update_automation_progress(automation_id, status='error', progress=100,
|
||||
phase='Error',
|
||||
log_line=f'Error: {str(e)}', log_type='error')
|
||||
finally:
|
||||
_resume_enrichment_workers(_ew_state, 'mirrored playlist discovery')
|
||||
|
||||
|
||||
def _extract_artist_name(artist):
|
||||
|
|
@ -22660,7 +22703,9 @@ def _discovery_score_candidates(source_title, source_artist, source_duration_ms,
|
|||
|
||||
def _run_tidal_discovery_worker(playlist_id):
|
||||
"""Background worker for Tidal discovery process (Spotify preferred, iTunes fallback)"""
|
||||
_ew_state = (False, False)
|
||||
try:
|
||||
_ew_state = _pause_enrichment_workers('Tidal discovery')
|
||||
state = tidal_discovery_states[playlist_id]
|
||||
playlist = state['playlist']
|
||||
|
||||
|
|
@ -22824,6 +22869,8 @@ def _run_tidal_discovery_worker(playlist_id):
|
|||
print(f"❌ Error in Tidal discovery worker: {e}")
|
||||
state['phase'] = 'error'
|
||||
state['status'] = f'error: {str(e)}'
|
||||
finally:
|
||||
_resume_enrichment_workers(_ew_state, 'Tidal discovery')
|
||||
|
||||
|
||||
def _search_spotify_for_tidal_track(tidal_track, use_spotify=True, itunes_client=None):
|
||||
|
|
@ -23385,7 +23432,9 @@ def update_youtube_discovery_match():
|
|||
|
||||
def _run_youtube_discovery_worker(url_hash):
|
||||
"""Background worker for YouTube music discovery process (Spotify preferred, iTunes fallback)"""
|
||||
_ew_state = (False, False)
|
||||
try:
|
||||
_ew_state = _pause_enrichment_workers('YouTube discovery')
|
||||
state = youtube_playlist_states[url_hash]
|
||||
playlist = state['playlist']
|
||||
tracks = playlist['tracks']
|
||||
|
|
@ -23689,10 +23738,14 @@ def _run_youtube_discovery_worker(url_hash):
|
|||
print(f"❌ Error in YouTube discovery worker: {e}")
|
||||
state['status'] = 'error'
|
||||
state['phase'] = 'fresh'
|
||||
finally:
|
||||
_resume_enrichment_workers(_ew_state, 'YouTube discovery')
|
||||
|
||||
def _run_listenbrainz_discovery_worker(playlist_mbid):
|
||||
"""Background worker for ListenBrainz music discovery process (Spotify preferred, iTunes fallback)"""
|
||||
_ew_state = (False, False)
|
||||
try:
|
||||
_ew_state = _pause_enrichment_workers('ListenBrainz discovery')
|
||||
state = listenbrainz_playlist_states[playlist_mbid]
|
||||
playlist = state['playlist']
|
||||
tracks = playlist['tracks']
|
||||
|
|
@ -23956,6 +24009,8 @@ def _run_listenbrainz_discovery_worker(playlist_mbid):
|
|||
print(f"❌ Error in ListenBrainz discovery worker: {e}")
|
||||
state['status'] = 'error'
|
||||
state['phase'] = 'fresh'
|
||||
finally:
|
||||
_resume_enrichment_workers(_ew_state, 'ListenBrainz discovery')
|
||||
|
||||
def _calculate_similarity(str1, str2):
|
||||
"""Calculate string similarity using simple character overlap"""
|
||||
|
|
@ -25855,8 +25910,7 @@ def start_watchlist_scan():
|
|||
# Start the scan in a background thread
|
||||
scan_profile_id = get_current_profile_id()
|
||||
def run_scan():
|
||||
_enrichment_was_running = False
|
||||
_itunes_enrichment_was_running = False
|
||||
_ew_state = (False, False)
|
||||
try:
|
||||
global watchlist_scan_state, watchlist_auto_scanning, watchlist_auto_scanning_timestamp
|
||||
from core.watchlist_scanner import WatchlistScanner
|
||||
|
|
@ -25925,14 +25979,7 @@ def start_watchlist_scan():
|
|||
scan_results = []
|
||||
|
||||
# Pause enrichment workers during scan to reduce API contention
|
||||
if spotify_enrichment_worker and not spotify_enrichment_worker.paused:
|
||||
spotify_enrichment_worker.pause()
|
||||
_enrichment_was_running = True
|
||||
print("⏸️ Paused Spotify enrichment worker during watchlist scan")
|
||||
if itunes_enrichment_worker and not itunes_enrichment_worker.paused:
|
||||
itunes_enrichment_worker.pause()
|
||||
_itunes_enrichment_was_running = True
|
||||
print("⏸️ Paused iTunes enrichment worker during watchlist scan")
|
||||
_ew_state = _pause_enrichment_workers('watchlist scan')
|
||||
|
||||
# Dynamic delay calculation based on scan scope
|
||||
lookback_period = scanner._get_lookback_period_setting()
|
||||
|
|
@ -26225,12 +26272,7 @@ def start_watchlist_scan():
|
|||
|
||||
finally:
|
||||
# Resume enrichment workers if we paused them
|
||||
if _enrichment_was_running and spotify_enrichment_worker:
|
||||
spotify_enrichment_worker.resume()
|
||||
print("▶️ Resumed Spotify enrichment worker after watchlist scan")
|
||||
if _itunes_enrichment_was_running and itunes_enrichment_worker:
|
||||
itunes_enrichment_worker.resume()
|
||||
print("▶️ Resumed iTunes enrichment worker after watchlist scan")
|
||||
_resume_enrichment_workers(_ew_state, 'watchlist scan')
|
||||
|
||||
# Always reset flag when scan completes (success or error)
|
||||
with watchlist_timer_lock:
|
||||
|
|
@ -26699,8 +26741,7 @@ def _process_watchlist_scan_automatically(automation_id=None):
|
|||
|
||||
print("🤖 [Auto-Watchlist] Timer triggered - starting automatic watchlist scan...")
|
||||
|
||||
_enrichment_was_running = False
|
||||
_itunes_enrichment_was_running = False
|
||||
_ew_state = (False, False)
|
||||
|
||||
try:
|
||||
# CRITICAL FIX: Use smart stuck detection BEFORE acquiring lock
|
||||
|
|
@ -26785,14 +26826,7 @@ def _process_watchlist_scan_automatically(automation_id=None):
|
|||
scan_results = []
|
||||
|
||||
# Pause enrichment workers during scan to reduce API contention
|
||||
if spotify_enrichment_worker and not spotify_enrichment_worker.paused:
|
||||
spotify_enrichment_worker.pause()
|
||||
_enrichment_was_running = True
|
||||
print("⏸️ [Auto-Watchlist] Paused Spotify enrichment worker during scan")
|
||||
if itunes_enrichment_worker and not itunes_enrichment_worker.paused:
|
||||
itunes_enrichment_worker.pause()
|
||||
_itunes_enrichment_was_running = True
|
||||
print("⏸️ [Auto-Watchlist] Paused iTunes enrichment worker during scan")
|
||||
_ew_state = _pause_enrichment_workers('auto-watchlist scan')
|
||||
|
||||
# Dynamic delay calculation based on scan scope
|
||||
lookback_period = scanner._get_lookback_period_setting()
|
||||
|
|
@ -27155,12 +27189,7 @@ def _process_watchlist_scan_automatically(automation_id=None):
|
|||
|
||||
finally:
|
||||
# Resume enrichment workers if we paused them
|
||||
if _enrichment_was_running and spotify_enrichment_worker:
|
||||
spotify_enrichment_worker.resume()
|
||||
print("▶️ [Auto-Watchlist] Resumed Spotify enrichment worker after scan")
|
||||
if _itunes_enrichment_was_running and itunes_enrichment_worker:
|
||||
itunes_enrichment_worker.resume()
|
||||
print("▶️ [Auto-Watchlist] Resumed iTunes enrichment worker after scan")
|
||||
_resume_enrichment_workers(_ew_state, 'auto-watchlist scan')
|
||||
|
||||
# Always reset flag
|
||||
with watchlist_timer_lock:
|
||||
|
|
@ -30815,7 +30844,9 @@ def clean_beatport_text(text):
|
|||
|
||||
def _run_beatport_discovery_worker(url_hash):
|
||||
"""Background worker for Beatport discovery process (Spotify preferred, iTunes fallback)"""
|
||||
_ew_state = (False, False)
|
||||
try:
|
||||
_ew_state = _pause_enrichment_workers('Beatport discovery')
|
||||
state = beatport_chart_states[url_hash]
|
||||
chart = state['chart']
|
||||
tracks = chart['tracks']
|
||||
|
|
@ -31111,6 +31142,8 @@ def _run_beatport_discovery_worker(url_hash):
|
|||
if url_hash in beatport_chart_states:
|
||||
beatport_chart_states[url_hash]['status'] = 'error'
|
||||
beatport_chart_states[url_hash]['phase'] = 'fresh'
|
||||
finally:
|
||||
_resume_enrichment_workers(_ew_state, 'Beatport discovery')
|
||||
|
||||
@app.route('/api/beatport/sync/start/<url_hash>', methods=['POST'])
|
||||
def start_beatport_sync(url_hash):
|
||||
|
|
|
|||
Loading…
Reference in a new issue