Handle finished downloads that weren't removed from the queue (#683)
In case a download was finished, but the downloader got stopped before it was able to remove the finished download from the queue, the downloader got stuck in an endless loop of starting and pausing downloads. This was caused by selecting the next chapter to download and then recognizing in "Downloader::step", that there is another chapter to download before the current one in the queue. However, since this recognized chapter is already downloaded, the downloader selected the next queued chapter again. It was then stuck in this loop until the finished chapter was manually removed from the queue.
This commit is contained in:
@@ -15,6 +15,7 @@ import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import mu.KLogger
|
||||
import mu.KotlinLogging
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
@@ -83,10 +84,17 @@ class Downloader(
|
||||
logger.debug { "stopped" }
|
||||
}
|
||||
|
||||
private suspend fun finishDownload(logger: KLogger, download: DownloadChapter) {
|
||||
downloadQueue.removeIf { it.mangaId == download.mangaId && it.chapterIndex == download.chapterIndex }
|
||||
step(null, false)
|
||||
logger.debug { "finished" }
|
||||
onDownloadFinished()
|
||||
}
|
||||
|
||||
private suspend fun run() {
|
||||
while (downloadQueue.isNotEmpty() && currentCoroutineContext().isActive) {
|
||||
val download = availableSourceDownloads.firstOrNull {
|
||||
(it.state == Queued || (it.state == Error && it.tries < 3)) // 3 re-tries per download
|
||||
(it.state == Queued || it.state == Finished || (it.state == Error && it.tries < 3)) // 3 re-tries per download
|
||||
} ?: break
|
||||
|
||||
val logContext = "${logger.name} - downloadChapter($download))"
|
||||
@@ -94,6 +102,14 @@ class Downloader(
|
||||
|
||||
downloadLogger.debug { "start" }
|
||||
|
||||
// handle cases were the downloader was stopped before the finished download could be removed from the queue
|
||||
// otherwise, it will create an endless loop, due to never removing the finished chapter and thinking that the
|
||||
// current download chapter was moved down in the queue
|
||||
if (download.state == Finished) {
|
||||
finishDownload(downloadLogger, download)
|
||||
break
|
||||
}
|
||||
|
||||
try {
|
||||
download.state = Downloading
|
||||
step(download, true)
|
||||
@@ -109,11 +125,7 @@ class Downloader(
|
||||
}
|
||||
}
|
||||
step(download, true)
|
||||
|
||||
downloadQueue.removeIf { it.mangaId == download.mangaId && it.chapterIndex == download.chapterIndex }
|
||||
step(null, false)
|
||||
downloadLogger.debug { "finished" }
|
||||
onDownloadFinished()
|
||||
finishDownload(downloadLogger, download)
|
||||
} catch (e: CancellationException) {
|
||||
logger.debug("Downloader was stopped")
|
||||
availableSourceDownloads.filter { it.state == Downloading }.forEach { it.state = Queued }
|
||||
|
||||
Reference in New Issue
Block a user