Streaming audio can make UI responsiveness very poor in the presence of network buffering
Steps to reproduce
- Have a Funkwhale server on one side of a 1 mbps link, with something like 375 kb or more of network buffering on the server's side of the slowest link (or about 3 seconds' worth).
- Fill it with 200 kbps MP3 files, which are perfectly streamable at that bandwidth.
- Open Funkwhale in the browser and clear out the queue.
- Start playing a song.
- While the song is playing, it is also still downloading. Try to navigate to other artists, albums, or songs in the right side of the UI while the song is downloading.
What happens?
Navigating in the right side will take about 5 or 10 seconds to load any page, while the song is still downloading.
What is expected?
You should be able to navigate nearly instantaneously, like you can when a song is not in the process of downloading, especially if you are going back from song page to an album page, or from an album page down to a song page to queue up the song.
Context
Funkwhale version(s) affected: 0.17.0
I'm using Funkwhale from Firefox, and running it in Docker.
I think the underlying problem is that Funkwhale is trying to send the audio data as fast as possible, and filling up the upload buffer between the server and the Internet, dropping and resending all the excess packets. The requests that it needs to make to update the UI when navigating between artists, albums, and tracks end up having to wait the duration of the buffer for each round trip, which can translate into even more latency for a full HTTP request/response.
Responsiveness could be substantially improved if the data needed to go back with the back button was cached locally at the client, and didn't have to be retrieved again from the server to display the previous page. If the data for the songs in an album could be fetched when the album itself was fetched, that would help too. But that's only a partial fix; as soon as you went to something not cached, it would still take a long time to get.
To solve this problem at Funkwhale's level, it looks like nginx would have to be set to rate limit its music streaming, either to some flat value configurable by the user, or dynamically to something like 1.1 times an individual file's bitrate.
Would it be easy to expose a flat bandwidth limit from the nginx Docker as an environment variable I can set in docker-compose.yml
? That's going to be easier for people to set up than the network-level QoS that would otherwise be required.
The actual solution here might also just be "fix the network not to have so much buffer bloat, this isn't Funkwhale's problem". But if one of the project's desired use cases is for people to spin up Funkwhale at home and access it elsewhere, it would be nice if it could deal well with poor network conditions, or at least be configurable to deal with them without requiring configuration changes elsewhere. Not every router actually has the QoS support needed to solve this at the router level, and setting it up at the Linux host level seems to require a bunch of manual tc
incantations.