mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-03 10:54:38 -05:00
Fix update subscription returning stale data (#727)
In case a manga was already loaded via the data loader, the cached data will get used. Due to this, the update status did not return the updated manga data, but instead, stale data
This commit is contained in:
@@ -41,6 +41,24 @@ class MangaType(
|
|||||||
var lastFetchedAt: Long?, // todo
|
var lastFetchedAt: Long?, // todo
|
||||||
var chaptersLastFetchedAt: Long?, // todo
|
var chaptersLastFetchedAt: Long?, // todo
|
||||||
) : Node {
|
) : Node {
|
||||||
|
companion object {
|
||||||
|
fun clearCacheFor(
|
||||||
|
mangaId: Int,
|
||||||
|
dataFetchingEnvironment: DataFetchingEnvironment,
|
||||||
|
) {
|
||||||
|
dataFetchingEnvironment.getDataLoader<List<Int>, MangaNodeList>("MangaDataLoader").clear(listOf(mangaId))
|
||||||
|
dataFetchingEnvironment.getDataLoader<List<Int>, MangaNodeList>("MangaForIdsDataLoader").clear(listOf(mangaId))
|
||||||
|
dataFetchingEnvironment.getDataLoader<Int, Int>("DownloadedChapterCountForMangaDataLoader").clear(mangaId)
|
||||||
|
dataFetchingEnvironment.getDataLoader<Int, Int>("UnreadChapterCountForMangaDataLoader").clear(mangaId)
|
||||||
|
dataFetchingEnvironment.getDataLoader<Int, Int>("LastReadChapterForMangaDataLoader").clear(mangaId)
|
||||||
|
dataFetchingEnvironment.getDataLoader<Int, ChapterNodeList>(
|
||||||
|
"ChaptersForMangaDataLoader",
|
||||||
|
).clear(mangaId)
|
||||||
|
dataFetchingEnvironment.getDataLoader<Int, Int>("MangaMetaDataLoader").clear(mangaId)
|
||||||
|
dataFetchingEnvironment.getDataLoader<Int, Int>("CategoriesForMangaDataLoader").clear(mangaId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor(row: ResultRow) : this(
|
constructor(row: ResultRow) : this(
|
||||||
row[MangaTable.id].value,
|
row[MangaTable.id].value,
|
||||||
row[MangaTable.sourceReference],
|
row[MangaTable.sourceReference],
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import suwayomi.tachidesk.manga.impl.update.JobStatus
|
|||||||
import suwayomi.tachidesk.manga.impl.update.UpdateStatus
|
import suwayomi.tachidesk.manga.impl.update.UpdateStatus
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
|
|
||||||
|
private val jobStatusToMangaIdsToCacheClearedStatus = mutableMapOf<JobStatus, MutableMap<Int, Boolean>>()
|
||||||
|
|
||||||
class UpdateStatus(
|
class UpdateStatus(
|
||||||
val isRunning: Boolean,
|
val isRunning: Boolean,
|
||||||
val skippedCategories: UpdateStatusCategoryType,
|
val skippedCategories: UpdateStatusCategoryType,
|
||||||
@@ -24,8 +26,22 @@ class UpdateStatus(
|
|||||||
updatingCategories = UpdateStatusCategoryType(status.categoryStatusMap[CategoryUpdateStatus.UPDATING]?.map { it.id }.orEmpty()),
|
updatingCategories = UpdateStatusCategoryType(status.categoryStatusMap[CategoryUpdateStatus.UPDATING]?.map { it.id }.orEmpty()),
|
||||||
pendingJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.PENDING]?.map { it.id }.orEmpty()),
|
pendingJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.PENDING]?.map { it.id }.orEmpty()),
|
||||||
runningJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.RUNNING]?.map { it.id }.orEmpty()),
|
runningJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.RUNNING]?.map { it.id }.orEmpty()),
|
||||||
completeJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.COMPLETE]?.map { it.id }.orEmpty()),
|
completeJobs =
|
||||||
failedJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.FAILED]?.map { it.id }.orEmpty()),
|
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()),
|
skippedJobs = UpdateStatusType(status.mangaStatusMap[JobStatus.SKIPPED]?.map { it.id }.orEmpty()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -42,8 +58,33 @@ class UpdateStatusCategoryType(
|
|||||||
class UpdateStatusType(
|
class UpdateStatusType(
|
||||||
@get:GraphQLIgnore
|
@get:GraphQLIgnore
|
||||||
val mangaIds: List<Int>,
|
val mangaIds: List<Int>,
|
||||||
|
private val jobStatus: JobStatus? = null,
|
||||||
|
private val isRunning: Boolean = false,
|
||||||
|
private val clearCache: Boolean = false,
|
||||||
) {
|
) {
|
||||||
fun mangas(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MangaNodeList> {
|
fun mangas(dataFetchingEnvironment: DataFetchingEnvironment): CompletableFuture<MangaNodeList> {
|
||||||
|
val resetClearedMangaIds = !isRunning && clearCache && jobStatus != null
|
||||||
|
if (resetClearedMangaIds) {
|
||||||
|
jobStatusToMangaIdsToCacheClearedStatus[jobStatus]?.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRunning && clearCache && jobStatus != null) {
|
||||||
|
val cacheClearedForMangaIds =
|
||||||
|
jobStatusToMangaIdsToCacheClearedStatus.getOrPut(
|
||||||
|
jobStatus,
|
||||||
|
) { emptyMap<Int, Boolean>().toMutableMap() }
|
||||||
|
|
||||||
|
mangaIds.forEach {
|
||||||
|
if (cacheClearedForMangaIds[it] == true) {
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
MangaType.clearCacheFor(it, dataFetchingEnvironment)
|
||||||
|
|
||||||
|
cacheClearedForMangaIds[it] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return dataFetchingEnvironment.getValueFromDataLoader<List<Int>, MangaNodeList>("MangaForIdsDataLoader", mangaIds)
|
return dataFetchingEnvironment.getValueFromDataLoader<List<Int>, MangaNodeList>("MangaForIdsDataLoader", mangaIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user