Prevent race conditions in wishlist downloads

Adds support for sending specific track IDs from the frontend to the backend when starting wishlist missing downloads. This ensures only the tracks currently visible to the user are processed, preventing race conditions if the wishlist changes between modal open and analysis start. Category filtering remains for backward compatibility.
This commit is contained in:
Broque Thomas 2025-12-07 14:43:43 -08:00
parent c237f354c4
commit 349d653ca0
2 changed files with 23 additions and 3 deletions

View file

@ -8294,6 +8294,7 @@ def start_wishlist_missing_downloads():
data = request.get_json() or {}
force_download_all = data.get('force_download_all', False)
category = data.get('category') # Get category filter (albums or singles)
track_ids = data.get('track_ids') # NEW: Get specific track IDs from frontend
from core.wishlist_service import get_wishlist_service
from database.music_database import MusicDatabase
@ -8371,8 +8372,21 @@ def start_wishlist_missing_downloads():
print(f"🔧 [Manual-Wishlist] Sanitized {len(wishlist_tracks)} tracks from wishlist service")
# FILTER BY CATEGORY if specified (same logic as auto-processing)
if category:
# FILTER BY TRACK IDs if specified (prioritized - prevents race conditions)
if track_ids:
# Convert to set for O(1) lookup
track_id_set = set(track_ids)
filtered_tracks = []
for track in wishlist_tracks:
spotify_track_id = track.get('spotify_track_id') or track.get('id')
if spotify_track_id in track_id_set:
filtered_tracks.append(track)
wishlist_tracks = filtered_tracks
print(f"🎯 [Manual-Wishlist] Filtered to {len(wishlist_tracks)} specific tracks by ID (preventing race condition)")
# FILTER BY CATEGORY if specified and no track_ids (backward compatibility)
elif category:
import json
filtered_tracks = []
for track in wishlist_tracks:

View file

@ -5529,12 +5529,18 @@ async function startWishlistMissingTracksProcess(playlistId) {
forceToggleContainer.style.display = 'none';
}
// Extract track IDs from what the user is currently seeing in the modal
// This prevents race conditions where wishlist changes between modal open and analysis start
const trackIds = process.tracks ? process.tracks.map(t => t.spotify_track_id || t.id).filter(id => id) : null;
console.log(`🎯 [Wishlist] Sending ${trackIds ? trackIds.length : 'all'} specific track IDs to prevent race condition`);
const response = await fetch('/api/wishlist/download_missing', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
force_download_all: forceDownloadAll,
category: window.currentWishlistCategory // Pass category to backend
category: window.currentWishlistCategory, // Keep for backward compat
track_ids: trackIds // NEW: Send exact tracks to process
})
});