From d219c5e3bbcfb24c40fa69e40bff11b6fd81fd7f Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Wed, 25 Feb 2026 16:22:20 +0600 Subject: [PATCH] Revert "Fix cache invalidation isn't done at startup (#2970)" This reverts commit e6cc38de0625f57df517343e16bc13349e42e00b. --- .../settings/screen/SettingsAdvancedScreen.kt | 7 +-- .../tachiyomi/data/download/DownloadCache.kt | 50 ++++++------------- 2 files changed, 17 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt index 6a31ca7d7..ef19d7398 100644 --- a/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/more/settings/screen/SettingsAdvancedScreen.kt @@ -176,7 +176,6 @@ object SettingsAdvancedScreen : SearchableSettings { private fun getDataGroup(): Preference.PreferenceGroup { val context = LocalContext.current val navigator = LocalNavigator.currentOrThrow - val scope = rememberCoroutineScope() return Preference.PreferenceGroup( title = stringResource(MR.strings.label_data), @@ -185,10 +184,8 @@ object SettingsAdvancedScreen : SearchableSettings { title = stringResource(MR.strings.pref_invalidate_download_cache), subtitle = stringResource(MR.strings.pref_invalidate_download_cache_summary), onClick = { - scope.launch { - Injekt.get().invalidateCache() - context.toast(MR.strings.download_cache_invalidated) - } + Injekt.get().invalidateCache() + context.toast(MR.strings.download_cache_invalidated) }, ), Preference.PreferenceItem.TextPreference( diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt index 84461c4b3..920be6172 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt @@ -12,17 +12,14 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.async import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.delay import kotlinx.coroutines.ensureActive import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.debounce -import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.receiveAsFlow @@ -112,19 +109,13 @@ class DownloadCache( ProtoBuf.decodeFromByteArray(it.readBytes()) } rootDownloadsDir = diskCache + lastRenew = System.currentTimeMillis() } } catch (e: Throwable) { logcat(LogPriority.ERROR, e) { "Failed to initialize from disk cache" } diskCacheFile.delete() } } - - sourceManager.catalogueSources - .map { sources -> sources.map { it.id }.toSet() } - .distinctUntilChanged() - .collect { - restartRenewal() - } } storageManager.changes @@ -337,34 +328,19 @@ class DownloadCache( notifyChanges() } - suspend fun invalidateCache() { - renewalJob?.cancelAndJoin() - diskCacheFile.delete() + fun invalidateCache() { 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() - lastRenew = 0L - renewCache(forceRenew = true) + diskCacheFile.delete() + renewCache() } /** * 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 - if ((!forceRenew && lastRenew + renewInterval >= System.currentTimeMillis()) || renewalJob?.isActive == true) { + if (lastRenew + renewInterval >= System.currentTimeMillis() || renewalJob?.isActive == true) { return } @@ -373,10 +349,15 @@ class DownloadCache( _isInitializing.emit(true) } - // Wait until sources are loaded. - sourceManager.catalogueSources.first { it.isNotEmpty() } + // Try to wait until extensions and sources have loaded + var sources = emptyList() + withTimeoutOrNull(30.seconds) { + extensionManager.isInitialized.first { it } + sourceManager.isInitialized.first { it } + + sources = getSources() + } - val sources = getSources() val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id } rootDownloadsDirMutex.withLock { @@ -449,9 +430,8 @@ class DownloadCache( private var updateDiskCacheJob: Job? = null private fun updateDiskCache() { - val previousJob = updateDiskCacheJob + updateDiskCacheJob?.cancel() updateDiskCacheJob = scope.launchIO { - previousJob?.cancelAndJoin() delay(1000) ensureActive() val bytes = ProtoBuf.encodeToByteArray(rootDownloadsDir)