From 16f9ca381e6f44ce26bc0ec16093884f931809e9 Mon Sep 17 00:00:00 2001 From: arkon Date: Fri, 12 Feb 2021 12:19:12 -0500 Subject: [PATCH] Make backup restoring logic more sequential (cherry picked from commit aded11e5996161036e3df01bacecdacb30f3e34b) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt # app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt --- .../data/backup/AbstractBackupRestore.kt | 4 +- .../data/backup/BackupRestoreService.kt | 14 +++- .../data/backup/full/FullBackupRestore.kt | 65 +++++++++---------- .../data/backup/legacy/LegacyBackupRestore.kt | 43 ++++++------ .../data/library/LibraryUpdateService.kt | 2 +- 5 files changed, 63 insertions(+), 65 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt index 9fc19d52d..6a5ac9ad2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt @@ -42,9 +42,9 @@ abstract class AbstractBackupRestore(protected val co protected val errors = mutableListOf>() - abstract fun performRestore(uri: Uri): Boolean + abstract suspend fun performRestore(uri: Uri): Boolean - fun restoreBackup(uri: Uri): Boolean { + suspend fun restoreBackup(uri: Uri): Boolean { val startTime = System.currentTimeMillis() restoreProgress = 0 errors.clear() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt index 10320b602..d057792dc 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupRestoreService.kt @@ -14,7 +14,10 @@ import eu.kanade.tachiyomi.data.notification.Notifications import eu.kanade.tachiyomi.util.system.acquireWakeLock import eu.kanade.tachiyomi.util.system.isServiceRunning import kotlinx.coroutines.CoroutineExceptionHandler -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import timber.log.Timber @@ -68,12 +71,14 @@ class BackupRestoreService : Service() { */ private lateinit var wakeLock: PowerManager.WakeLock + private lateinit var ioScope: CoroutineScope private var backupRestore: AbstractBackupRestore<*>? = null private lateinit var notifier: BackupNotifier override fun onCreate() { super.onCreate() + ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) notifier = BackupNotifier(this) wakeLock = acquireWakeLock(javaClass.name) @@ -92,6 +97,7 @@ class BackupRestoreService : Service() { private fun destroyJob() { backupRestore?.job?.cancel() + ioScope?.cancel() if (wakeLock.isHeld) { wakeLock.release() } @@ -122,6 +128,7 @@ class BackupRestoreService : Service() { BackupConst.BACKUP_TYPE_FULL -> FullBackupRestore(this, notifier, online) else -> LegacyBackupRestore(this, notifier) } + val handler = CoroutineExceptionHandler { _, exception -> Timber.e(exception) backupRestore?.writeErrorLog() @@ -129,14 +136,15 @@ class BackupRestoreService : Service() { notifier.showRestoreError(exception.message) stopSelf(startId) } - backupRestore?.job = GlobalScope.launch(handler) { + val job = ioScope.launch(handler) { if (backupRestore?.restoreBackup(uri) == false) { notifier.showRestoreError(getString(R.string.restoring_backup_canceled)) } } - backupRestore?.job?.invokeOnCompletion { + job.invokeOnCompletion { stopSelf(startId) } + backupRestore?.job = job return START_NOT_STICKY } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt index b4f65877f..63c6aa848 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt @@ -17,7 +17,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.online.all.MergedSource -import eu.kanade.tachiyomi.util.lang.launchIO import exh.EXHMigrations import exh.source.MERGED_SOURCE_ID import okio.buffer @@ -27,7 +26,7 @@ import java.util.Date class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore(context, notifier) { - override fun performRestore(uri: Uri): Boolean { + override suspend fun performRestore(uri: Uri): Boolean { // SY --> throttleManager.resetThrottle() // SY <-- @@ -82,7 +81,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val } // SY <-- - private fun restoreManga(backupManga: BackupManga, backupCategories: List, online: Boolean) { + private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List, online: Boolean) { var manga = backupManga.getMangaImpl() val chapters = backupManga.getChaptersImpl() val categories = backupManga.categories @@ -124,7 +123,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val * @param history history data from json * @param tracks tracking data from json */ - private fun restoreMangaData( + private suspend fun restoreMangaData( manga: Manga, source: Source?, chapters: List, @@ -158,7 +157,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val * @param chapters chapters of manga that needs updating * @param categories categories that need updating */ - private fun restoreMangaFetch( + private suspend fun restoreMangaFetch( source: Source?, manga: Manga, chapters: List, @@ -170,31 +169,29 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val flatMetadata: BackupFlatMetadata?, online: Boolean ) { - launchIO { - try { - val fetchedManga = backupManager.restoreMangaFetch(source, manga, online) - fetchedManga.id ?: (return@launchIO) + try { + val fetchedManga = backupManager.restoreMangaFetch(source, manga, online) + fetchedManga.id ?: return - if (online && source != null) { - // SY --> - if (source !is MergedSource) { - updateChapters(source, fetchedManga, chapters) - } - // SY <-- - } else { - backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters) + if (online && source != null) { + // SY --> + if (source !is MergedSource) { + updateChapters(source, fetchedManga, chapters) } - - restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata) - - updateTracking(fetchedManga, tracks) - } catch (e: Exception) { - errors.add(Date() to "${manga.title} - ${e.message}") + // SY <-- + } else { + backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters) } + + restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata) + + updateTracking(fetchedManga, tracks) + } catch (e: Exception) { + errors.add(Date() to "${manga.title} - ${e.message}") } } - private fun restoreMangaNoFetch( + private suspend fun restoreMangaNoFetch( source: Source?, backupManga: Manga, chapters: List, @@ -206,19 +203,17 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val flatMetadata: BackupFlatMetadata?, online: Boolean ) { - launchIO { - if (online && source != null) { - if (/* SY --> */ source !is MergedSource && /* SY <-- */ !backupManager.restoreChaptersForManga(backupManga, chapters)) { - updateChapters(source, backupManga, chapters) - } - } else { - backupManager.restoreChaptersForMangaOffline(backupManga, chapters) + if (online && source != null) { + if (/* SY --> */ source !is MergedSource && /* SY <-- */ !backupManager.restoreChaptersForManga(backupManga, chapters)) { + updateChapters(source, backupManga, chapters) } - - restoreExtraForManga(backupManga, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata) - - updateTracking(backupManga, tracks) + } else { + backupManager.restoreChaptersForMangaOffline(backupManga, chapters) } + + restoreExtraForManga(backupManga, categories, history, tracks, backupCategories, mergedMangaReferences, flatMetadata) + + updateTracking(backupManga, tracks) } private suspend fun restoreExtraForManga(manga: Manga, categories: List, history: List, tracks: List, backupCategories: List, mergedMangaReferences: List, flatMetadata: BackupFlatMetadata?) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt b/app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt index 3ac6e0979..2d1c53c4f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt @@ -21,13 +21,12 @@ import eu.kanade.tachiyomi.data.database.models.MangaImpl import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.TrackImpl import eu.kanade.tachiyomi.source.Source -import eu.kanade.tachiyomi.util.lang.launchIO import exh.EXHMigrations import java.util.Date class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore(context, notifier) { - override fun performRestore(uri: Uri): Boolean { + override suspend fun performRestore(uri: Uri): Boolean { // SY --> throttleManager.resetThrottle() // SY <-- @@ -91,7 +90,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract } // SY <-- - private fun restoreManga(mangaJson: JsonObject) { + private suspend fun restoreManga(mangaJson: JsonObject) { /* SY --> */ var /* SY <-- */ manga = backupManager.parser.fromJson( mangaJson.get( Backup.MANGA @@ -145,7 +144,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract * @param history history data from json * @param tracks tracking data from json */ - private fun restoreMangaData( + private suspend fun restoreMangaData( manga: Manga, source: Source, chapters: List, @@ -175,7 +174,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract * @param chapters chapters of manga that needs updating * @param categories categories that need updating */ - private fun restoreMangaFetch( + private suspend fun restoreMangaFetch( source: Source, manga: Manga, chapters: List, @@ -183,23 +182,21 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract history: List, tracks: List ) { - launchIO { - try { - val fetchedManga = backupManager.fetchManga(source, manga) - fetchedManga.id ?: (return@launchIO) + try { + val fetchedManga = backupManager.fetchManga(source, manga) + fetchedManga.id ?: return - updateChapters(source, fetchedManga, chapters) + updateChapters(source, fetchedManga, chapters) - restoreExtraForManga(fetchedManga, categories, history, tracks) + restoreExtraForManga(fetchedManga, categories, history, tracks) - updateTracking(fetchedManga, tracks) - } catch (e: Exception) { - errors.add(Date() to "${manga.title} - ${e.message}") - } + updateTracking(fetchedManga, tracks) + } catch (e: Exception) { + errors.add(Date() to "${manga.title} - ${e.message}") } } - private fun restoreMangaNoFetch( + private suspend fun restoreMangaNoFetch( source: Source, backupManga: Manga, chapters: List, @@ -207,15 +204,13 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract history: List, tracks: List ) { - launchIO { - if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { - updateChapters(source, backupManga, chapters) - } - - restoreExtraForManga(backupManga, categories, history, tracks) - - updateTracking(backupManga, tracks) + if (!backupManager.restoreChaptersForManga(backupManga, chapters)) { + updateChapters(source, backupManga, chapters) } + + restoreExtraForManga(backupManga, categories, history, tracks) + + updateTracking(backupManga, tracks) } private fun restoreExtraForManga(manga: Manga, categories: List, history: List, tracks: List) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index e19121815..af94c14fa 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -193,8 +193,8 @@ class LibraryUpdateService( * lock. */ override fun onDestroy() { - ioScope?.cancel() updateJob?.cancel() + ioScope?.cancel() if (wakeLock.isHeld) { wakeLock.release() }