Merge pull request #5620 from Bnyro/master

fix: reduce concurrency of playlist import api calls
This commit is contained in:
Bnyro 2024-02-11 13:03:30 +01:00 committed by GitHub
commit d1edf7ecd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -27,6 +27,7 @@ import kotlinx.coroutines.withContext
object PlaylistsHelper { object PlaylistsHelper {
private val pipedPlaylistRegex = private val pipedPlaylistRegex =
"[\\da-fA-F]{8}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{12}".toRegex() "[\\da-fA-F]{8}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{4}-[\\da-fA-F]{12}".toRegex()
private const val MAX_CONCURRENT_IMPORT_CALLS = 5
private val token get() = PreferenceHelper.getToken() private val token get() = PreferenceHelper.getToken()
val loggedIn: Boolean get() = token.isNotEmpty() val loggedIn: Boolean get() = token.isNotEmpty()
@ -59,6 +60,7 @@ object PlaylistsHelper {
"alphabetic" -> playlists.sortedBy { it.name?.lowercase() } "alphabetic" -> playlists.sortedBy { it.name?.lowercase() }
"alphabetic_reversed" -> playlists.sortedBy { it.name?.lowercase() } "alphabetic_reversed" -> playlists.sortedBy { it.name?.lowercase() }
.reversed() .reversed()
else -> playlists else -> playlists
} }
} }
@ -176,34 +178,25 @@ object PlaylistsHelper {
suspend fun importPlaylists(playlists: List<PipedImportPlaylist>) = suspend fun importPlaylists(playlists: List<PipedImportPlaylist>) =
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
playlists.map { playlist -> for (playlist in playlists) {
val playlistId = createPlaylist(playlist.name!!) val playlistId = createPlaylist(playlist.name!!) ?: return@withContext
async { // if logged in, add the playlists by their ID via an api call
playlistId ?: return@async if (loggedIn) {
// if logged in, add the playlists by their ID via an api call val streams = playlist.videos.map { StreamItem(url = it) }
if (loggedIn) { addToPlaylist(playlistId, *streams.toTypedArray())
addToPlaylist( } else {
playlistId, // if not logged in, all video information needs to become fetched manually
*playlist.videos.map { // Only do so with `MAX_CONCURRENT_IMPORT_CALLS` videos at once to prevent performance issues
StreamItem(url = it) val streams = playlist.videos.chunked(MAX_CONCURRENT_IMPORT_CALLS).map { videos ->
}.toTypedArray() videos.parallelMap {
) runCatching { RetrofitInstance.api.getStreams(it) }
} else { .getOrNull()
// if not logged in, all video information needs to become fetched manually ?.toStreamItem(it)
// Only do so with 20 videos at once to prevent performance issues }.filterNotNull()
val streams = playlist.videos.mapIndexed { index, id -> id to index } }.flatten()
.groupBy { it.second % 20 }.map { (_, videos) -> addToPlaylist(playlistId, *streams.toTypedArray())
videos.parallelMap {
runCatching {
RetrofitInstance.api.getStreams(it.first)
.toStreamItem(it.first)
}
}.mapNotNull { it.getOrNull() }
}
addToPlaylist(playlistId, *streams.flatten().toTypedArray())
}
} }
}.awaitAll() }
} }
suspend fun exportPipedPlaylists(): List<PipedImportPlaylist> = withContext(Dispatchers.IO) { suspend fun exportPipedPlaylists(): List<PipedImportPlaylist> = withContext(Dispatchers.IO) {