Parallel cover update job

This commit is contained in:
arkon 2021-07-09 17:49:46 -04:00
parent 714aa4b4ba
commit 015e8deb79

View file

@ -54,6 +54,9 @@ import timber.log.Timber
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
/** /**
* This class will take care of updating the chapters of the manga from the library. It can be * This class will take care of updating the chapters of the manga from the library. It can be
@ -273,11 +276,11 @@ class LibraryUpdateService(
*/ */
suspend fun updateChapterList() { suspend fun updateChapterList() {
val semaphore = Semaphore(5) val semaphore = Semaphore(5)
var progressCount = 0 val progressCount = AtomicInteger(0)
val currentlyUpdatingManga = mutableListOf<LibraryManga>() val currentlyUpdatingManga = CopyOnWriteArrayList<LibraryManga>()
val newUpdates = mutableListOf<Pair<LibraryManga, Array<Chapter>>>() val newUpdates = CopyOnWriteArrayList<Pair<LibraryManga, Array<Chapter>>>()
val failedUpdates = mutableListOf<Pair<Manga, String?>>() val failedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
var hasDownloads = false val hasDownloads = AtomicBoolean(false)
val loggedServices by lazy { trackManager.services.filter { it.isLogged } } val loggedServices by lazy { trackManager.services.filter { it.isLogged } }
withIOContext { withIOContext {
@ -292,10 +295,10 @@ class LibraryUpdateService(
} }
currentlyUpdatingManga.add(manga) currentlyUpdatingManga.add(manga)
progressCount++ progressCount.andIncrement
notifier.showProgressNotification( notifier.showProgressNotification(
currentlyUpdatingManga, currentlyUpdatingManga,
progressCount, progressCount.get(),
mangaToUpdate.size mangaToUpdate.size
) )
@ -305,7 +308,7 @@ class LibraryUpdateService(
if (newChapters.isNotEmpty()) { if (newChapters.isNotEmpty()) {
if (manga.shouldDownloadNewChapters(db, preferences)) { if (manga.shouldDownloadNewChapters(db, preferences)) {
downloadChapters(manga, newChapters) downloadChapters(manga, newChapters)
hasDownloads = true hasDownloads.set(true)
} }
// Convert to the manga that contains new chapters // Convert to the manga that contains new chapters
@ -327,7 +330,7 @@ class LibraryUpdateService(
currentlyUpdatingManga.remove(manga) currentlyUpdatingManga.remove(manga)
notifier.showProgressNotification( notifier.showProgressNotification(
currentlyUpdatingManga, currentlyUpdatingManga,
progressCount, progressCount.get(),
mangaToUpdate.size mangaToUpdate.size
) )
} }
@ -341,7 +344,7 @@ class LibraryUpdateService(
if (newUpdates.isNotEmpty()) { if (newUpdates.isNotEmpty()) {
notifier.showUpdateNotifications(newUpdates) notifier.showUpdateNotifications(newUpdates)
if (hasDownloads) { if (hasDownloads.get()) {
DownloadService.start(this) DownloadService.start(this)
} }
} }
@ -397,29 +400,56 @@ class LibraryUpdateService(
} }
private suspend fun updateCovers() { private suspend fun updateCovers() {
var progressCount = 0 val semaphore = Semaphore(5)
val progressCount = AtomicInteger(0)
val currentlyUpdatingManga = CopyOnWriteArrayList<LibraryManga>()
mangaToUpdate.forEach { manga -> withIOContext {
if (updateJob?.isActive != true) { mangaToUpdate.groupBy { it.source }
return .values
} .map { mangaInSource ->
async {
semaphore.withPermit {
mangaInSource.forEach { manga ->
if (updateJob?.isActive != true) {
return@async
}
notifier.showProgressNotification(listOf(manga), progressCount++, mangaToUpdate.size) currentlyUpdatingManga.add(manga)
progressCount.andIncrement
notifier.showProgressNotification(
currentlyUpdatingManga,
progressCount.get(),
mangaToUpdate.size
)
sourceManager.get(manga.source)?.let { source -> sourceManager.get(manga.source)?.let { source ->
try { try {
val networkManga = source.getMangaDetails(manga.toMangaInfo()) val networkManga =
val sManga = networkManga.toSManga() source.getMangaDetails(manga.toMangaInfo())
manga.prepUpdateCover(coverCache, sManga, true) val sManga = networkManga.toSManga()
sManga.thumbnail_url?.let { manga.prepUpdateCover(coverCache, sManga, true)
manga.thumbnail_url = it sManga.thumbnail_url?.let {
db.insertManga(manga).executeAsBlocking() manga.thumbnail_url = it
db.insertManga(manga).executeAsBlocking()
}
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
}
}
currentlyUpdatingManga.remove(manga)
notifier.showProgressNotification(
currentlyUpdatingManga,
progressCount.get(),
mangaToUpdate.size
)
}
}
} }
} catch (e: Throwable) {
// Ignore errors and continue
Timber.e(e)
} }
} .awaitAll()
} }
coverCache.clearMemoryCache() coverCache.clearMemoryCache()