Fix deadlocks in gallery adder, favorites sync and backup/restore
This commit is contained in:
parent
24e10d6037
commit
6951ce34c7
@ -46,11 +46,13 @@ interface LewdSource<M : RaisedSearchMetadata, I> : CatalogueSource {
|
||||
fun parseToManga(manga: SManga, input: I): Completable {
|
||||
val mangaId = (manga as? Manga)?.id
|
||||
val metaObservable = if(mangaId != null) {
|
||||
db.getFlatMetadataForManga(mangaId).asRxSingle()
|
||||
.map {
|
||||
if(it != null) it.raise(metaClass)
|
||||
else newMetaInstance()
|
||||
}
|
||||
// We have to use fromCallable because StorIO messes up the thread scheduling if we use their rx functions
|
||||
Single.fromCallable {
|
||||
db.getFlatMetadataForManga(mangaId).executeAsBlocking()
|
||||
} .map {
|
||||
if(it != null) it.raise(metaClass)
|
||||
else newMetaInstance()
|
||||
}
|
||||
} else {
|
||||
Single.just(newMetaInstance())
|
||||
}
|
||||
@ -76,10 +78,12 @@ interface LewdSource<M : RaisedSearchMetadata, I> : CatalogueSource {
|
||||
*/
|
||||
fun getOrLoadMetadata(mangaId: Long?, inputProducer: () -> Single<I>): Single<M> {
|
||||
val metaObservable = if(mangaId != null) {
|
||||
db.getFlatMetadataForManga(mangaId).asRxSingle()
|
||||
.map {
|
||||
it?.raise(metaClass)
|
||||
}
|
||||
// We have to use fromCallable because StorIO messes up the thread scheduling if we use their rx functions
|
||||
Single.fromCallable {
|
||||
db.getFlatMetadataForManga(mangaId).executeAsBlocking()
|
||||
}.map {
|
||||
it?.raise(metaClass)
|
||||
}
|
||||
} else Single.just(null)
|
||||
|
||||
return metaObservable.flatMap { existingMeta ->
|
||||
|
@ -3,6 +3,7 @@ package exh.favorites
|
||||
import android.content.Context
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.PowerManager
|
||||
import com.elvishew.xlog.XLog
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
@ -21,7 +22,6 @@ import exh.util.trans
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.Request
|
||||
import rx.subjects.BehaviorSubject
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
@ -47,6 +47,8 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
private var wifiLock: WifiManager.WifiLock? = null
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
|
||||
private val logger = XLog.tag("EHFavSync").build()
|
||||
|
||||
val status = BehaviorSubject.create<FavoritesSyncStatus>(FavoritesSyncStatus.Idle())
|
||||
|
||||
@Synchronized
|
||||
@ -73,7 +75,7 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
exh.fetchFavorites()
|
||||
} catch(e: Exception) {
|
||||
status.onNext(FavoritesSyncStatus.Error("Failed to fetch favorites from remote server!"))
|
||||
Timber.e(e, "Could not fetch favorites!")
|
||||
logger.e( "Could not fetch favorites!", e)
|
||||
return
|
||||
}
|
||||
|
||||
@ -125,11 +127,11 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
}
|
||||
} catch(e: IgnoredException) {
|
||||
//Do not display error as this error has already been reported
|
||||
Timber.w(e, "Ignoring exception!")
|
||||
logger.w( "Ignoring exception!", e)
|
||||
return
|
||||
} catch (e: Exception) {
|
||||
status.onNext(FavoritesSyncStatus.Error("Unknown error: ${e.message}"))
|
||||
Timber.e(e, "Sync error!")
|
||||
logger.e( "Sync error!", e)
|
||||
return
|
||||
} finally {
|
||||
//Release wake + wifi locks
|
||||
@ -228,7 +230,7 @@ class FavoritesSyncHelper(val context: Context) {
|
||||
break
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Sync network error!")
|
||||
logger.w( "Sync network error!", e)
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,7 +383,7 @@ sealed class FavoritesSyncStatus(val message: String) {
|
||||
class Idle : FavoritesSyncStatus("Waiting for sync to start")
|
||||
class Initializing : FavoritesSyncStatus("Initializing sync")
|
||||
class Processing(message: String, isThrottle: Boolean = false) : FavoritesSyncStatus(if(isThrottle)
|
||||
(message + "\n\nSync is currently throttling (to avoid being banned from ExHentai) and may take a long time to complete.")
|
||||
"$message\n\nSync is currently throttling (to avoid being banned from ExHentai) and may take a long time to complete."
|
||||
else
|
||||
message)
|
||||
class CompleteWithErrors(messages: List<String>) : FavoritesSyncStatus(messages.joinToString("\n"))
|
||||
|
@ -24,14 +24,15 @@ data class FlatMetadata(
|
||||
}
|
||||
|
||||
fun DatabaseHelper.getFlatMetadataForManga(mangaId: Long): PreparedOperation<FlatMetadata?> {
|
||||
fun getSingle() = getSearchMetadataForManga(mangaId).asRxSingle().flatMap { meta ->
|
||||
if(meta == null) Single.just(null)
|
||||
else Single.zip(
|
||||
getSearchTagsForManga(mangaId).asRxSingle(),
|
||||
getSearchTitlesForManga(mangaId).asRxSingle()
|
||||
) { tags, titles ->
|
||||
// We have to use fromCallable because StorIO messes up the thread scheduling if we use their rx functions
|
||||
fun getSingle() = Single.fromCallable {
|
||||
val meta = getSearchMetadataForManga(mangaId).executeAsBlocking()
|
||||
if(meta != null) {
|
||||
val tags = getSearchTagsForManga(mangaId).executeAsBlocking()
|
||||
val titles = getSearchTitlesForManga(mangaId).executeAsBlocking()
|
||||
|
||||
FlatMetadata(meta, tags, titles)
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
return object : PreparedOperation<FlatMetadata?> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user