From 1bfe30b2169d071d1e2664bb8fc701550790b49f Mon Sep 17 00:00:00 2001 From: Josh Patra Date: Tue, 10 Feb 2026 12:14:38 -0500 Subject: [PATCH] v1.2.4: stop racing SquidWTF endpoints for better throughput Use round-robin instead of racing to enable parallel processing of 12 tracks simultaneously (one per endpoint) instead of racing all endpoints for each track. --- .../Spotify/SpotifyTrackMatchingService.cs | 3 ++- .../SquidWTF/SquidWTFMetadataService.cs | 24 +++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/allstarr/Services/Spotify/SpotifyTrackMatchingService.cs b/allstarr/Services/Spotify/SpotifyTrackMatchingService.cs index bd45db5..31c3245 100644 --- a/allstarr/Services/Spotify/SpotifyTrackMatchingService.cs +++ b/allstarr/Services/Spotify/SpotifyTrackMatchingService.cs @@ -992,7 +992,8 @@ public class SpotifyTrackMatchingService : BackgroundService headers["X-Emby-Authorization"] = $"MediaBrowser Token=\"{jellyfinSettings.ApiKey}\""; } - var playlistItemsUrl = $"Playlists/{jellyfinPlaylistId}/Items?UserId={userId}&Fields=MediaSources"; + // Request all fields that clients typically need (not just MediaSources) + var playlistItemsUrl = $"Playlists/{jellyfinPlaylistId}/Items?UserId={userId}&Fields=Genres,DateCreated,MediaSources,ParentId,People,Tags,SortName,ProviderIds"; var (existingTracksResponse, statusCode) = await proxyService.GetJsonAsync(playlistItemsUrl, null, headers); if (statusCode != 200 || existingTracksResponse == null) diff --git a/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs b/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs index 4198929..22531bb 100644 --- a/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs +++ b/allstarr/Services/SquidWTF/SquidWTFMetadataService.cs @@ -86,19 +86,19 @@ public class SquidWTFMetadataService : IMusicMetadataService public async Task> SearchSongsAsync(string query, int limit = 20) { - // Race all endpoints for fastest search results - return await _fallbackHelper.RaceAllEndpointsAsync(async (baseUrl, ct) => + // Use round-robin to distribute load across endpoints (allows parallel processing of multiple tracks) + return await _fallbackHelper.TryWithFallbackAsync(async (baseUrl) => { // Use 's' parameter for track search as per hifi-api spec var url = $"{baseUrl}/search/?s={Uri.EscapeDataString(query)}"; - var response = await _httpClient.GetAsync(url, ct); + var response = await _httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"HTTP {response.StatusCode}"); } - var json = await response.Content.ReadAsStringAsync(ct); + var json = await response.Content.ReadAsStringAsync(); // Check for error in response body var result = JsonDocument.Parse(json); @@ -132,19 +132,19 @@ public class SquidWTFMetadataService : IMusicMetadataService public async Task> SearchAlbumsAsync(string query, int limit = 20) { - // Race all endpoints for fastest search results - return await _fallbackHelper.RaceAllEndpointsAsync(async (baseUrl, ct) => + // Use round-robin to distribute load across endpoints (allows parallel processing) + return await _fallbackHelper.TryWithFallbackAsync(async (baseUrl) => { // Note: hifi-api doesn't document album search, but 'al' parameter is commonly used var url = $"{baseUrl}/search/?al={Uri.EscapeDataString(query)}"; - var response = await _httpClient.GetAsync(url, ct); + var response = await _httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { throw new HttpRequestException($"HTTP {response.StatusCode}"); } - var json = await response.Content.ReadAsStringAsync(ct); + var json = await response.Content.ReadAsStringAsync(); var result = JsonDocument.Parse(json); var albums = new List(); @@ -169,14 +169,14 @@ public class SquidWTFMetadataService : IMusicMetadataService public async Task> SearchArtistsAsync(string query, int limit = 20) { - // Race all endpoints for fastest search results - return await _fallbackHelper.RaceAllEndpointsAsync(async (baseUrl, ct) => + // Use round-robin to distribute load across endpoints (allows parallel processing) + return await _fallbackHelper.TryWithFallbackAsync(async (baseUrl) => { // Per hifi-api spec: use 'a' parameter for artist search var url = $"{baseUrl}/search/?a={Uri.EscapeDataString(query)}"; _logger.LogInformation("🔍 SQUIDWTF: Searching artists with URL: {Url}", url); - var response = await _httpClient.GetAsync(url, ct); + var response = await _httpClient.GetAsync(url); if (!response.IsSuccessStatusCode) { @@ -184,7 +184,7 @@ public class SquidWTFMetadataService : IMusicMetadataService throw new HttpRequestException($"HTTP {response.StatusCode}"); } - var json = await response.Content.ReadAsStringAsync(ct); + var json = await response.Content.ReadAsStringAsync(); var result = JsonDocument.Parse(json); var artists = new List();