Skip to content

Optimize Jellyfin API Requests#236

Open
MattKercher wants to merge 24 commits into
Jeffser:mainfrom
MattKercher:feature/optimize-jellyfin
Open

Optimize Jellyfin API Requests#236
MattKercher wants to merge 24 commits into
Jeffser:mainfrom
MattKercher:feature/optimize-jellyfin

Conversation

@MattKercher

Copy link
Copy Markdown
Contributor

The Jellyfin /Items endpoint, particularly on Jellyfin 10.11.x, can be extremely slow, especially on servers with a ton of music tracks. This PR optimizes requests by reducing round trips to the server and by reducing the amount of background threads. From my testing, requests now take about 25% of the time that they used to for my Jellyfin server. Honestly, this started as a pretty small change and ended up expanding out into a bunch of changes, so I'm really sorry if the PR is kind of large. For an exhaustive list of changes:

Jellyfin-Specific Integration Changes:

  • Modifies the verifySong/Album/Artist/Playlist functions to be more reusable functions meant for parsing API responses to the GObject models.
    • Allows passing response objects directly to the functions as an optional argument to skip re-fetching the same information.
    • Introduces an optional lite boolean argument to exclude unnecessary information that's not used by rows/buttons.
  • Adds a self._bulk_verify function to iterate through API response lists and send each response object to the verify functions to write them to loaded_models instead of relying on buttons/rows to fetch the information themselves.
    • getAlbumList()/getRandomSongs()/getArtists()/getPlaylists() uses this function to write their response lists to loaded_models instead of doing it manually.
    • The search() function used to completely rely on the buttons/rows calling their corresponding verify function despite having already retrieved the item lists from the API, so now search writes its response lists to loaded_models using bulk_verify similar to the methods above.
  • Fixes fetching similar artists in verifyArtist() function.
  • Switches to /Artist/AlbumArtist endpoint for fetching artists, as the /Items endpoint returns artist folders instead of AlbumArtists.
  • Scopes GET requests to the user's music library, falling back to use all libraries if multiple music libraries are present on the Jellyfin server.
  • Uses the coverArt field in the models for the full coverArt URL and sets it to "None" if no cover art exists for that item in order to prevent unnecessary 404 errors. It also gets the image ID and sends it as a GET parameter for use as a potential cache buster in the future.
  • Sets a timeout on all API requests so background workers don't hang indefinitely.

Other Integration Changes:

  • Adds a ThreadExecutorPool to the Base model as self.threads and switches Jellyfin and Navidrome to use it. This restricts how many background threads can be spawned to at once to 30 and queues any additional threads in order to prevent hammering the server with API requests and to prevent the network connection pool from filling up.
  • requests.Session is apparently not thread safe, so self.session now returns a new session object whenever it's called.
    • Every instance of calling self.session uses the with operator now to ensure that the session is properly closed.

Album Button:

  • The artist button was throwing an occasional error because the associated artist_id wasn't present in loaded_models yet, so now set_action_name() is called from the update_artist_id() instead of being set in the associated Blueprint file. I'm not sure if this is the best approach, but it seemed to fix the problem.

I tried to test as thoroughly as possible, but since I don't have a Navidrome instance I had to test against the Navidrome demo. Hopefully that was sufficient, since I didn't substantially change the Navidrome integration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant