Skip to content

Commit

Permalink
Merge pull request #3594 from nichwall/filter_data_longer_cache
Browse files Browse the repository at this point in the history
Increase cache time for `filterdata` in library
  • Loading branch information
advplyr authored Nov 16, 2024
2 parents 45f8b06 + e8d8b67 commit 4c88e9c
Showing 1 changed file with 141 additions and 0 deletions.
141 changes: 141 additions & 0 deletions server/utils/queries/libraryFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,65 @@ module.exports = {
languages: new Set(),
publishers: new Set(),
publishedDecades: new Set(),
bookCount: 0, // How many books returned from database query
authorCount: 0, // How many authors returned from database query
seriesCount: 0, // How many series returned from database query
podcastCount: 0, // How many podcasts returned from database query
numIssues: 0
}

const lastLoadedAt = cachedFilterData ? cachedFilterData.loadedAt : 0

if (mediaType === 'podcast') {
// Check how many podcasts are in library to determine if we need to load all of the data
// This is done to handle the edge case of podcasts having been deleted and not having
// an updatedAt timestamp to trigger a reload of the filter data
const podcastCountFromDatabase = await Database.podcastModel.count({
include: {
model: Database.libraryItemModel,
attributes: [],
where: {
libraryId: libraryId
}
}
})

// To reduce the cold-start load time, first check if any podcasts
// have an "updatedAt" timestamp since the last time the filter
// data was loaded. If so, we can skip loading all of the data.
// Because many items could change, just check the count of items instead
// of actually loading the data twice
const changedPodcasts = await Database.podcastModel.count({
include: {
model: Database.libraryItemModel,
attributes: [],
where: {
libraryId: libraryId,
updatedAt: {
[Sequelize.Op.gt]: new Date(lastLoadedAt)
}
}
},
where: {
updatedAt: {
[Sequelize.Op.gt]: new Date(lastLoadedAt)
}
},
limit: 1
})

if (changedPodcasts === 0) {
// If nothing has changed, check if the number of podcasts in
// library is still the same as prior check before updating cache creation time

if (podcastCountFromDatabase === Database.libraryFilterData[libraryId].podcastCount) {
Logger.debug(`Filter data for ${libraryId} has not changed, returning cached data and updating cache time after ${((Date.now() - start) / 1000).toFixed(2)}s`)
Database.libraryFilterData[libraryId].loadedAt = Date.now()
return cachedFilterData
}
}

// Something has changed in the podcasts table, so reload all of the filter data for library
const podcasts = await Database.podcastModel.findAll({
include: {
model: Database.libraryItemModel,
Expand All @@ -484,7 +539,93 @@ module.exports = {
data.languages.add(podcast.language)
}
}

// Set podcast count for later comparison
data.podcastCount = podcastCountFromDatabase
} else {
const bookCountFromDatabase = await Database.bookModel.count({
include: {
model: Database.libraryItemModel,
attributes: [],
where: {
libraryId: libraryId
}
}
})

const seriesCountFromDatabase = await Database.seriesModel.count({
where: {
libraryId: libraryId
}
})

const authorCountFromDatabase = await Database.authorModel.count({
where: {
libraryId: libraryId
}
})

// To reduce the cold-start load time, first check if any library items, series,
// or authors have an "updatedAt" timestamp since the last time the filter
// data was loaded. If so, we can skip loading all of the data.
// Because many items could change, just check the count of items instead
// of actually loading the data twice

const changedBooks = await Database.bookModel.count({
include: {
model: Database.libraryItemModel,
attributes: [],
where: {
libraryId: libraryId,
updatedAt: {
[Sequelize.Op.gt]: new Date(lastLoadedAt)
}
}
},
where: {
updatedAt: {
[Sequelize.Op.gt]: new Date(lastLoadedAt)
}
},
limit: 1
})

const changedSeries = await Database.seriesModel.count({
where: {
libraryId: libraryId,
updatedAt: {
[Sequelize.Op.gt]: new Date(lastLoadedAt)
}
},
limit: 1
})

const changedAuthors = await Database.authorModel.count({
where: {
libraryId: libraryId,
updatedAt: {
[Sequelize.Op.gt]: new Date(lastLoadedAt)
}
},
limit: 1
})

if (changedBooks + changedSeries + changedAuthors === 0) {
// If nothing has changed, check if the number of authors, series, and books
// matches the prior check before updating cache creation time
if (bookCountFromDatabase === Database.libraryFilterData[libraryId].bookCount && seriesCountFromDatabase === Database.libraryFilterData[libraryId].seriesCount && authorCountFromDatabase === Database.libraryFilterData[libraryId].authorCount) {
Logger.debug(`Filter data for ${libraryId} has not changed, returning cached data and updating cache time after ${((Date.now() - start) / 1000).toFixed(2)}s`)
Database.libraryFilterData[libraryId].loadedAt = Date.now()
return cachedFilterData
}
}

// Store the counts for later comparison
data.bookCount = bookCountFromDatabase
data.seriesCount = seriesCountFromDatabase
data.authorCount = authorCountFromDatabase

// Something has changed in one of the tables, so reload all of the filter data for library
const books = await Database.bookModel.findAll({
include: {
model: Database.libraryItemModel,
Expand Down

0 comments on commit 4c88e9c

Please sign in to comment.