From e7cb88c7573f3c1c27bdc0155cbef506c2958d7e Mon Sep 17 00:00:00 2001 From: Valter Martinek Date: Wed, 16 Nov 2022 17:33:51 +0100 Subject: [PATCH] Download queue missing update fix (#450) * Add immediate updates to download queue manager for updates that always needs to be delivered * Update server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/DownloadManager.kt Co-authored-by: Mitchell Syer * Revert change to make sure that data in status sent to client are actual * Reduce number of immediate updates to clients Co-authored-by: Mitchell Syer --- .../manga/impl/download/DownloadManager.kt | 24 ++++++++++++------- .../manga/impl/download/Downloader.kt | 22 ++++++++--------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/DownloadManager.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/DownloadManager.kt index f85c85f7..7ddd40d5 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/DownloadManager.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/DownloadManager.kt @@ -80,17 +80,25 @@ object DownloadManager { init { scope.launch { notifyFlow.sample(1.seconds).collect { - val status = getStatus() - clients.forEach { - it.value.send(status) - } + sendStatusToAllClients() } } } - private fun notifyAllClients() { - scope.launch { - notifyFlow.emit(Unit) + private fun sendStatusToAllClients() { + val status = getStatus() + clients.forEach { + it.value.send(status) + } + } + + private fun notifyAllClients(immediate: Boolean = false) { + if (immediate) { + sendStatusToAllClients() + } else { + scope.launch { + notifyFlow.emit(Unit) + } } } @@ -206,7 +214,7 @@ object DownloadManager { val addedChapters = inputs.mapNotNull { addToQueue(it.first, it.second) } if (addedChapters.isNotEmpty()) { start() - notifyAllClients() + notifyAllClients(true) } scope.launch { downloaderWatch.emit(Unit) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/Downloader.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/Downloader.kt index 30b7a921..c1cb1983 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/Downloader.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/Downloader.kt @@ -39,15 +39,15 @@ class Downloader( private val scope: CoroutineScope, val sourceId: Long, private val downloadQueue: CopyOnWriteArrayList, - private val notifier: () -> Unit, + private val notifier: (immediate: Boolean) -> Unit, private val onComplete: () -> Unit ) { private var job: Job? = null class StopDownloadException : Exception("Cancelled download") class PauseDownloadException : Exception("Pause download") - private suspend fun step(download: DownloadChapter?) { - notifier() + private suspend fun step(download: DownloadChapter?, immediate: Boolean) { + notifier(immediate) currentCoroutineContext().ensureActive() if (download != null && download != downloadQueue.firstOrNull { it.manga.sourceId.toLong() == sourceId && it.state != Error }) { if (download in downloadQueue) { @@ -74,7 +74,7 @@ class Downloader( } } - notifier() + notifier(false) } suspend fun stop() { @@ -90,10 +90,10 @@ class Downloader( try { download.state = Downloading - step(download) + step(download, true) download.chapter = getChapterDownloadReady(download.chapterIndex, download.mangaId) - step(download) + step(download, false) val pageCount = download.chapter.pageCount for (pageNum in 0 until pageCount) { @@ -109,7 +109,7 @@ class Downloader( .distinctUntilChanged() .onEach { download.progress = (pageNum.toFloat() + (it.toFloat() * 0.01f)) / pageCount - step(null) // don't throw on canceled download here since we can't do anything + step(null, false) // don't throw on canceled download here since we can't do anything } .launchIn(scope) } @@ -120,7 +120,7 @@ class Downloader( } // TODO: retry on error with 2,4,8 seconds of wait download.progress = ((pageNum + 1).toFloat()) / pageCount - step(download) + step(download, false) } download.state = Finished transaction { @@ -128,10 +128,10 @@ class Downloader( it[isDownloaded] = true } } - step(download) + step(download, true) downloadQueue.removeIf { it.mangaId == download.mangaId && it.chapterIndex == download.chapterIndex } - step(null) + step(null, false) } catch (e: CancellationException) { logger.debug("Downloader was stopped") downloadQueue.filter { it.state == Downloading }.forEach { it.state = Queued } @@ -142,7 +142,7 @@ class Downloader( download.tries++ download.state = Error } finally { - notifier() + notifier(false) } } }