Revert "Reapply "Fix cache invalidation isn't done at startup (#2970)""

This reverts commit c17e9573b7.
This commit is contained in:
Jobobby04
2026-04-08 14:52:15 -04:00
parent 5c14879c12
commit 170358f88e
2 changed files with 14 additions and 41 deletions
@@ -223,7 +223,6 @@ object SettingsAdvancedScreen : SearchableSettings {
private fun getDataGroup(): Preference.PreferenceGroup { private fun getDataGroup(): Preference.PreferenceGroup {
val context = LocalContext.current val context = LocalContext.current
val navigator = LocalNavigator.currentOrThrow val navigator = LocalNavigator.currentOrThrow
val scope = rememberCoroutineScope()
return Preference.PreferenceGroup( return Preference.PreferenceGroup(
title = stringResource(MR.strings.label_data), title = stringResource(MR.strings.label_data),
@@ -232,10 +231,8 @@ object SettingsAdvancedScreen : SearchableSettings {
title = stringResource(MR.strings.pref_invalidate_download_cache), title = stringResource(MR.strings.pref_invalidate_download_cache),
subtitle = stringResource(MR.strings.pref_invalidate_download_cache_summary), subtitle = stringResource(MR.strings.pref_invalidate_download_cache_summary),
onClick = { onClick = {
scope.launch { Injekt.get<DownloadCache>().invalidateCache()
Injekt.get<DownloadCache>().invalidateCache() context.toast(MR.strings.download_cache_invalidated)
context.toast(MR.strings.download_cache_invalidated)
}
}, },
), ),
Preference.PreferenceItem.TextPreference( Preference.PreferenceItem.TextPreference(
@@ -12,17 +12,14 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
@@ -112,19 +109,13 @@ class DownloadCache(
ProtoBuf.decodeFromByteArray<RootDirectory>(it.readBytes()) ProtoBuf.decodeFromByteArray<RootDirectory>(it.readBytes())
} }
rootDownloadsDir = diskCache rootDownloadsDir = diskCache
lastRenew = System.currentTimeMillis()
} }
} catch (e: Throwable) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e) { "Failed to initialize from disk cache" } logcat(LogPriority.ERROR, e) { "Failed to initialize from disk cache" }
diskCacheFile.delete() diskCacheFile.delete()
} }
} }
sourceManager.catalogueSources
.map { sources -> sources.map { it.id }.toSet() }
.distinctUntilChanged()
.collect {
restartRenewal()
}
} }
storageManager.changes storageManager.changes
@@ -362,34 +353,19 @@ class DownloadCache(
notifyChanges() notifyChanges()
} }
suspend fun invalidateCache() { fun invalidateCache() {
renewalJob?.cancelAndJoin()
diskCacheFile.delete()
lastRenew = 0L lastRenew = 0L
renewCache(forceRenew = true)
}
/**
* Safely cancels any in-progress renewal job, resets the last-renew timestamp, and
* immediately starts a new renewal, bypassing the time-based throttle.
*/
private fun restartRenewal() {
renewalJob?.cancel() renewalJob?.cancel()
lastRenew = 0L diskCacheFile.delete()
renewCache(forceRenew = true) renewCache()
} }
/** /**
* Renews the downloads cache. * Renews the downloads cache.
*
* @param forceRenew when `true`, the time-based throttle is bypassed. Use this after
* explicitly cancelling the previous job to avoid a race where the cancelled job's
* [invokeOnCompletion] handler sets [lastRenew] after the reset but before the new
* job's guard check.
*/ */
private fun renewCache(forceRenew: Boolean = false) { private fun renewCache() {
// Avoid renewing cache if in the process nor too often // Avoid renewing cache if in the process nor too often
if ((!forceRenew && lastRenew + renewInterval >= System.currentTimeMillis()) || renewalJob?.isActive == true) { if (lastRenew + renewInterval >= System.currentTimeMillis() || renewalJob?.isActive == true) {
return return
} }
@@ -400,14 +376,15 @@ class DownloadCache(
// Try to wait until extensions and sources have loaded // Try to wait until extensions and sources have loaded
// SY --> // SY -->
var sources = emptyList<Source>()
withTimeoutOrNull(30.seconds) { withTimeoutOrNull(30.seconds) {
// SY <-- extensionManager.isInitialized.first { it }
sourceManager.catalogueSources.first { it.isNotEmpty() } sourceManager.isInitialized.first { it }
// SY -->
sources = getSources()
} }
// SY <-- // SY <--
val sources = getSources()
val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id } val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id }
rootDownloadsDirMutex.withLock { rootDownloadsDirMutex.withLock {
@@ -482,9 +459,8 @@ class DownloadCache(
private var updateDiskCacheJob: Job? = null private var updateDiskCacheJob: Job? = null
private fun updateDiskCache() { private fun updateDiskCache() {
val previousJob = updateDiskCacheJob updateDiskCacheJob?.cancel()
updateDiskCacheJob = scope.launchIO { updateDiskCacheJob = scope.launchIO {
previousJob?.cancelAndJoin()
delay(1000) delay(1000)
ensureActive() ensureActive()
val bytes = ProtoBuf.encodeToByteArray(rootDownloadsDir) val bytes = ProtoBuf.encodeToByteArray(rootDownloadsDir)