diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt index d006f82ee..75858e3dd 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/MangaType.kt @@ -41,6 +41,24 @@ class MangaType( var lastFetchedAt: Long?, // todo var chaptersLastFetchedAt: Long?, // todo ) : Node { + companion object { + fun clearCacheFor( + mangaId: Int, + dataFetchingEnvironment: DataFetchingEnvironment, + ) { + dataFetchingEnvironment.getDataLoader, MangaNodeList>("MangaDataLoader").clear(listOf(mangaId)) + dataFetchingEnvironment.getDataLoader, MangaNodeList>("MangaForIdsDataLoader").clear(listOf(mangaId)) + dataFetchingEnvironment.getDataLoader("DownloadedChapterCountForMangaDataLoader").clear(mangaId) + dataFetchingEnvironment.getDataLoader("UnreadChapterCountForMangaDataLoader").clear(mangaId) + dataFetchingEnvironment.getDataLoader("LastReadChapterForMangaDataLoader").clear(mangaId) + dataFetchingEnvironment.getDataLoader( + "ChaptersForMangaDataLoader", + ).clear(mangaId) + dataFetchingEnvironment.getDataLoader("MangaMetaDataLoader").clear(mangaId) + dataFetchingEnvironment.getDataLoader("CategoriesForMangaDataLoader").clear(mangaId) + } + } + constructor(row: ResultRow) : this( row[MangaTable.id].value, row[MangaTable.sourceReference], diff --git a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/UpdateType.kt b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/UpdateType.kt index e91291d11..dbf691f26 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/UpdateType.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/graphql/types/UpdateType.kt @@ -8,6 +8,8 @@ import suwayomi.tachidesk.manga.impl.update.JobStatus import suwayomi.tachidesk.manga.impl.update.UpdateStatus import java.util.concurrent.CompletableFuture +private val jobStatusToMangaIdsToCacheClearedStatus = mutableMapOf>() + class UpdateStatus( val isRunning: Boolean, val skippedCategories: UpdateStatusCategoryType, @@ -24,8 +26,22 @@ class UpdateStatus( updatingCategories = UpdateStatusCategoryType(status.categoryStatusMap[CategoryUpdateStatus.UPDATING]?.map { it.id }.orEmpty()), pendingJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.PENDING]?.map { it.id }.orEmpty()), runningJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.RUNNING]?.map { it.id }.orEmpty()), - completeJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.COMPLETE]?.map { it.id }.orEmpty()), - failedJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.FAILED]?.map { it.id }.orEmpty()), + completeJobs = + UpdateStatusType( + status.mangaStatusMap[JobStatus.COMPLETE]?.map { + it.id + }.orEmpty(), + JobStatus.COMPLETE, + status.running, + true, + ), + failedJobs = + UpdateStatusType( + status.mangaStatusMap[JobStatus.FAILED]?.map { it.id }.orEmpty(), + JobStatus.FAILED, + status.running, + true, + ), skippedJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.SKIPPED]?.map { it.id }.orEmpty()), ) } @@ -42,8 +58,33 @@ class UpdateStatusCategoryType( class UpdateStatusType( @get:GraphQLIgnore val mangaIds: List, + private val jobStatus: JobStatus? = null, + private val isRunning: Boolean = false, + private val clearCache: Boolean = false, ) { fun mangas(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture { + val resetClearedMangaIds = !isRunning && clearCache && jobStatus != null + if (resetClearedMangaIds) { + jobStatusToMangaIdsToCacheClearedStatus[jobStatus]?.clear() + } + + if (isRunning && clearCache && jobStatus != null) { + val cacheClearedForMangaIds = + jobStatusToMangaIdsToCacheClearedStatus.getOrPut( + jobStatus, + ) { emptyMap().toMutableMap() } + + mangaIds.forEach { + if (cacheClearedForMangaIds[it] == true) { + return@forEach + } + + MangaType.clearCacheFor(it, dataFetchingEnvironment) + + cacheClearedForMangaIds[it] = true + } + } + return dataFetchingEnvironment.getValueFromDataLoader, MangaNodeList>("MangaForIdsDataLoader", mangaIds) } }