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.
This commit is contained in:
2026-02-10 12:14:38 -05:00
parent c9c82a650d
commit 1bfe30b216
2 changed files with 14 additions and 13 deletions

View File

@@ -992,7 +992,8 @@ public class SpotifyTrackMatchingService : BackgroundService
headers["X-Emby-Authorization"] = $"MediaBrowser Token=\"{jellyfinSettings.ApiKey}\""; 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); var (existingTracksResponse, statusCode) = await proxyService.GetJsonAsync(playlistItemsUrl, null, headers);
if (statusCode != 200 || existingTracksResponse == null) if (statusCode != 200 || existingTracksResponse == null)

View File

@@ -86,19 +86,19 @@ public class SquidWTFMetadataService : IMusicMetadataService
public async Task<List<Song>> SearchSongsAsync(string query, int limit = 20) public async Task<List<Song>> SearchSongsAsync(string query, int limit = 20)
{ {
// Race all endpoints for fastest search results // Use round-robin to distribute load across endpoints (allows parallel processing of multiple tracks)
return await _fallbackHelper.RaceAllEndpointsAsync(async (baseUrl, ct) => return await _fallbackHelper.TryWithFallbackAsync(async (baseUrl) =>
{ {
// Use 's' parameter for track search as per hifi-api spec // Use 's' parameter for track search as per hifi-api spec
var url = $"{baseUrl}/search/?s={Uri.EscapeDataString(query)}"; var url = $"{baseUrl}/search/?s={Uri.EscapeDataString(query)}";
var response = await _httpClient.GetAsync(url, ct); var response = await _httpClient.GetAsync(url);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
throw new HttpRequestException($"HTTP {response.StatusCode}"); 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 // Check for error in response body
var result = JsonDocument.Parse(json); var result = JsonDocument.Parse(json);
@@ -132,19 +132,19 @@ public class SquidWTFMetadataService : IMusicMetadataService
public async Task<List<Album>> SearchAlbumsAsync(string query, int limit = 20) public async Task<List<Album>> SearchAlbumsAsync(string query, int limit = 20)
{ {
// Race all endpoints for fastest search results // Use round-robin to distribute load across endpoints (allows parallel processing)
return await _fallbackHelper.RaceAllEndpointsAsync(async (baseUrl, ct) => return await _fallbackHelper.TryWithFallbackAsync(async (baseUrl) =>
{ {
// Note: hifi-api doesn't document album search, but 'al' parameter is commonly used // Note: hifi-api doesn't document album search, but 'al' parameter is commonly used
var url = $"{baseUrl}/search/?al={Uri.EscapeDataString(query)}"; var url = $"{baseUrl}/search/?al={Uri.EscapeDataString(query)}";
var response = await _httpClient.GetAsync(url, ct); var response = await _httpClient.GetAsync(url);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
throw new HttpRequestException($"HTTP {response.StatusCode}"); 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 result = JsonDocument.Parse(json);
var albums = new List<Album>(); var albums = new List<Album>();
@@ -169,14 +169,14 @@ public class SquidWTFMetadataService : IMusicMetadataService
public async Task<List<Artist>> SearchArtistsAsync(string query, int limit = 20) public async Task<List<Artist>> SearchArtistsAsync(string query, int limit = 20)
{ {
// Race all endpoints for fastest search results // Use round-robin to distribute load across endpoints (allows parallel processing)
return await _fallbackHelper.RaceAllEndpointsAsync(async (baseUrl, ct) => return await _fallbackHelper.TryWithFallbackAsync(async (baseUrl) =>
{ {
// Per hifi-api spec: use 'a' parameter for artist search // Per hifi-api spec: use 'a' parameter for artist search
var url = $"{baseUrl}/search/?a={Uri.EscapeDataString(query)}"; var url = $"{baseUrl}/search/?a={Uri.EscapeDataString(query)}";
_logger.LogInformation("🔍 SQUIDWTF: Searching artists with URL: {Url}", url); _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) if (!response.IsSuccessStatusCode)
{ {
@@ -184,7 +184,7 @@ public class SquidWTFMetadataService : IMusicMetadataService
throw new HttpRequestException($"HTTP {response.StatusCode}"); 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 result = JsonDocument.Parse(json);
var artists = new List<Artist>(); var artists = new List<Artist>();