Эх сурвалжийг харах

Make backup restoring logic more sequential

arkon 4 жил өмнө
parent
commit
aded11e599

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/backup/AbstractBackupRestore.kt

@@ -37,9 +37,9 @@ abstract class AbstractBackupRestore<T : AbstractBackupManager>(protected val co
 
     protected val errors = mutableListOf<Pair<Date, String>>()
 
-    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()

+ 11 - 3
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
     }

+ 27 - 32
app/src/main/java/eu/kanade/tachiyomi/data/backup/full/FullBackupRestore.kt

@@ -13,7 +13,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
 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.util.lang.launchIO
 import okio.buffer
 import okio.gzip
 import okio.source
@@ -21,7 +20,7 @@ import java.util.Date
 
 class FullBackupRestore(context: Context, notifier: BackupNotifier, private val online: Boolean) : AbstractBackupRestore<FullBackupManager>(context, notifier) {
 
-    override fun performRestore(uri: Uri): Boolean {
+    override suspend fun performRestore(uri: Uri): Boolean {
         backupManager = FullBackupManager(context)
 
         val backupString = context.contentResolver.openInputStream(uri)!!.source().gzip().buffer().use { it.readByteArray() }
@@ -58,7 +57,7 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
         showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories))
     }
 
-    private fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) {
+    private suspend fun restoreManga(backupManga: BackupManga, backupCategories: List<BackupCategory>, online: Boolean) {
         val manga = backupManga.getMangaImpl()
         val chapters = backupManga.getChaptersImpl()
         val categories = backupManga.categories
@@ -92,7 +91,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<Chapter>,
@@ -124,7 +123,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<Chapter>,
@@ -134,27 +133,25 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
         backupCategories: List<BackupCategory>,
         online: Boolean
     ) {
-        launchIO {
-            try {
-                val fetchedManga = backupManager.restoreMangaFetch(source, manga, online)
-                fetchedManga.id ?: (return@launchIO)
-
-                if (online && source != null) {
-                    updateChapters(source, fetchedManga, chapters)
-                } else {
-                    backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters)
-                }
-
-                restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories)
-
-                updateTracking(fetchedManga, tracks)
-            } catch (e: Exception) {
-                errors.add(Date() to "${manga.title} - ${e.message}")
+        try {
+            val fetchedManga = backupManager.restoreMangaFetch(source, manga, online)
+            fetchedManga.id ?: return
+
+            if (online && source != null) {
+                updateChapters(source, fetchedManga, chapters)
+            } else {
+                backupManager.restoreChaptersForMangaOffline(fetchedManga, chapters)
             }
+
+            restoreExtraForManga(fetchedManga, categories, history, tracks, backupCategories)
+
+            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<Chapter>,
@@ -164,19 +161,17 @@ class FullBackupRestore(context: Context, notifier: BackupNotifier, private val
         backupCategories: List<BackupCategory>,
         online: Boolean
     ) {
-        launchIO {
-            if (online && source != null) {
-                if (!backupManager.restoreChaptersForManga(backupManga, chapters)) {
-                    updateChapters(source, backupManga, chapters)
-                }
-            } else {
-                backupManager.restoreChaptersForMangaOffline(backupManga, chapters)
+        if (online && source != null) {
+            if (!backupManager.restoreChaptersForManga(backupManga, chapters)) {
+                updateChapters(source, backupManga, chapters)
             }
+        } else {
+            backupManager.restoreChaptersForMangaOffline(backupManga, chapters)
+        }
 
-            restoreExtraForManga(backupManga, categories, history, tracks, backupCategories)
+        restoreExtraForManga(backupManga, categories, history, tracks, backupCategories)
 
-            updateTracking(backupManga, tracks)
-        }
+        updateTracking(backupManga, tracks)
     }
 
     private fun restoreExtraForManga(manga: Manga, categories: List<Int>, history: List<BackupHistory>, tracks: List<Track>, backupCategories: List<BackupCategory>) {

+ 18 - 23
app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/LegacyBackupRestore.kt

@@ -21,12 +21,11 @@ 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 java.util.Date
 
 class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : AbstractBackupRestore<LegacyBackupManager>(context, notifier) {
 
-    override fun performRestore(uri: Uri): Boolean {
+    override suspend fun performRestore(uri: Uri): Boolean {
         val reader = JsonReader(context.contentResolver.openInputStream(uri)!!.bufferedReader())
         val json = JsonParser.parseReader(reader).asJsonObject
 
@@ -63,7 +62,7 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
         showRestoreProgress(restoreProgress, restoreAmount, context.getString(R.string.categories))
     }
 
-    private fun restoreManga(mangaJson: JsonObject) {
+    private suspend fun restoreManga(mangaJson: JsonObject) {
         val manga = backupManager.parser.fromJson<MangaImpl>(
             mangaJson.get(
                 Backup.MANGA
@@ -113,7 +112,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<Chapter>,
@@ -143,7 +142,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<Chapter>,
@@ -151,23 +150,21 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
         history: List<DHistory>,
         tracks: List<Track>
     ) {
-        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<Chapter>,
@@ -175,15 +172,13 @@ class LegacyBackupRestore(context: Context, notifier: BackupNotifier) : Abstract
         history: List<DHistory>,
         tracks: List<Track>
     ) {
-        launchIO {
-            if (!backupManager.restoreChaptersForManga(backupManga, chapters)) {
-                updateChapters(source, backupManga, chapters)
-            }
+        if (!backupManager.restoreChaptersForManga(backupManga, chapters)) {
+            updateChapters(source, backupManga, chapters)
+        }
 
-            restoreExtraForManga(backupManga, categories, history, tracks)
+        restoreExtraForManga(backupManga, categories, history, tracks)
 
-            updateTracking(backupManga, tracks)
-        }
+        updateTracking(backupManga, tracks)
     }
 
     private fun restoreExtraForManga(manga: Manga, categories: List<String>, history: List<DHistory>, tracks: List<Track>) {

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt

@@ -158,8 +158,8 @@ class LibraryUpdateService(
      * lock.
      */
     override fun onDestroy() {
-        ioScope?.cancel()
         updateJob?.cancel()
+        ioScope?.cancel()
         if (wakeLock.isHeld) {
             wakeLock.release()
         }