Fix:Automatic library scans using stale copy of library object resulting in reverting saved changes to it #3079 #2894

This commit is contained in:
advplyr 2024-06-20 17:08:18 -05:00
parent 2ec49cbdb1
commit 72c1407aa7

View File

@ -16,7 +16,7 @@ class CronManager {
/** /**
* Initialize library scan crons & podcast download crons * Initialize library scan crons & podcast download crons
* @param {oldLibrary[]} libraries * @param {import('../objects/Library')[]} libraries
*/ */
async init(libraries) { async init(libraries) {
this.initLibraryScanCrons(libraries) this.initLibraryScanCrons(libraries)
@ -25,7 +25,7 @@ class CronManager {
/** /**
* Initialize library scan crons * Initialize library scan crons
* @param {oldLibrary[]} libraries * @param {import('../objects/Library')[]} libraries
*/ */
initLibraryScanCrons(libraries) { initLibraryScanCrons(libraries) {
for (const library of libraries) { for (const library of libraries) {
@ -35,27 +35,37 @@ class CronManager {
} }
} }
startCronForLibrary(library) { /**
Logger.debug(`[CronManager] Init library scan cron for ${library.name} on schedule ${library.settings.autoScanCronExpression}`) * Start cron schedule for library
const libScanCron = cron.schedule(library.settings.autoScanCronExpression, () => { *
Logger.debug(`[CronManager] Library scan cron executing for ${library.name}`) * @param {import('../objects/Library')} _library
LibraryScanner.scan(library) */
startCronForLibrary(_library) {
Logger.debug(`[CronManager] Init library scan cron for ${_library.name} on schedule ${_library.settings.autoScanCronExpression}`)
const libScanCron = cron.schedule(_library.settings.autoScanCronExpression, async () => {
const library = await Database.libraryModel.getOldById(_library.id)
if (!library) {
Logger.error(`[CronManager] Library not found for scan cron ${_library.id}`)
} else {
Logger.debug(`[CronManager] Library scan cron executing for ${library.name}`)
LibraryScanner.scan(library)
}
}) })
this.libraryScanCrons.push({ this.libraryScanCrons.push({
libraryId: library.id, libraryId: _library.id,
expression: library.settings.autoScanCronExpression, expression: _library.settings.autoScanCronExpression,
task: libScanCron task: libScanCron
}) })
} }
removeCronForLibrary(library) { removeCronForLibrary(library) {
Logger.debug(`[CronManager] Removing library scan cron for ${library.name}`) Logger.debug(`[CronManager] Removing library scan cron for ${library.name}`)
this.libraryScanCrons = this.libraryScanCrons.filter(lsc => lsc.libraryId !== library.id) this.libraryScanCrons = this.libraryScanCrons.filter((lsc) => lsc.libraryId !== library.id)
} }
updateLibraryScanCron(library) { updateLibraryScanCron(library) {
const expression = library.settings.autoScanCronExpression const expression = library.settings.autoScanCronExpression
const existingCron = this.libraryScanCrons.find(lsc => lsc.libraryId === library.id) const existingCron = this.libraryScanCrons.find((lsc) => lsc.libraryId === library.id)
if (!expression && existingCron) { if (!expression && existingCron) {
if (existingCron.task.stop) existingCron.task.stop() if (existingCron.task.stop) existingCron.task.stop()
@ -128,7 +138,7 @@ class CronManager {
} }
async executePodcastCron(expression) { async executePodcastCron(expression) {
const podcastCron = this.podcastCrons.find(cron => cron.expression === expression) const podcastCron = this.podcastCrons.find((cron) => cron.expression === expression)
if (!podcastCron) { if (!podcastCron) {
Logger.error(`[CronManager] Podcast cron not found for expression ${expression}`) Logger.error(`[CronManager] Podcast cron not found for expression ${expression}`)
return return
@ -144,7 +154,7 @@ class CronManager {
const libraryItem = await Database.libraryItemModel.getOldById(libraryItemId) const libraryItem = await Database.libraryItemModel.getOldById(libraryItemId)
if (!libraryItem) { if (!libraryItem) {
Logger.error(`[CronManager] Library item ${libraryItemId} not found for episode check cron ${expression}`) Logger.error(`[CronManager] Library item ${libraryItemId} not found for episode check cron ${expression}`)
podcastCron.libraryItemIds = podcastCron.libraryItemIds.filter(lid => lid !== libraryItemId) // Filter it out podcastCron.libraryItemIds = podcastCron.libraryItemIds.filter((lid) => lid !== libraryItemId) // Filter it out
} else { } else {
libraryItems.push(libraryItem) libraryItems.push(libraryItem)
} }
@ -153,8 +163,9 @@ class CronManager {
// Run episode checks // Run episode checks
for (const libraryItem of libraryItems) { for (const libraryItem of libraryItems) {
const keepAutoDownloading = await this.podcastManager.runEpisodeCheck(libraryItem) const keepAutoDownloading = await this.podcastManager.runEpisodeCheck(libraryItem)
if (!keepAutoDownloading) { // auto download was disabled if (!keepAutoDownloading) {
podcastCron.libraryItemIds = podcastCron.libraryItemIds.filter(lid => lid !== libraryItem.id) // Filter it out // auto download was disabled
podcastCron.libraryItemIds = podcastCron.libraryItemIds.filter((lid) => lid !== libraryItem.id) // Filter it out
} }
} }
@ -165,20 +176,20 @@ class CronManager {
} }
Logger.debug(`[CronManager] Finished executing podcast cron ${expression} for ${libraryItems.length} item(s)`) Logger.debug(`[CronManager] Finished executing podcast cron ${expression} for ${libraryItems.length} item(s)`)
this.podcastCronExpressionsExecuting = this.podcastCronExpressionsExecuting.filter(exp => exp !== expression) this.podcastCronExpressionsExecuting = this.podcastCronExpressionsExecuting.filter((exp) => exp !== expression)
} }
removePodcastEpisodeCron(podcastCron) { removePodcastEpisodeCron(podcastCron) {
Logger.info(`[CronManager] Stopping & removing podcast episode cron for ${podcastCron.expression}`) Logger.info(`[CronManager] Stopping & removing podcast episode cron for ${podcastCron.expression}`)
if (podcastCron.task) podcastCron.task.stop() if (podcastCron.task) podcastCron.task.stop()
this.podcastCrons = this.podcastCrons.filter(pc => pc.expression !== podcastCron.expression) this.podcastCrons = this.podcastCrons.filter((pc) => pc.expression !== podcastCron.expression)
} }
checkUpdatePodcastCron(libraryItem) { checkUpdatePodcastCron(libraryItem) {
// Remove from old cron by library item id // Remove from old cron by library item id
const existingCron = this.podcastCrons.find(pc => pc.libraryItemIds.includes(libraryItem.id)) const existingCron = this.podcastCrons.find((pc) => pc.libraryItemIds.includes(libraryItem.id))
if (existingCron) { if (existingCron) {
existingCron.libraryItemIds = existingCron.libraryItemIds.filter(lid => lid !== libraryItem.id) existingCron.libraryItemIds = existingCron.libraryItemIds.filter((lid) => lid !== libraryItem.id)
if (!existingCron.libraryItemIds.length) { if (!existingCron.libraryItemIds.length) {
this.removePodcastEpisodeCron(existingCron) this.removePodcastEpisodeCron(existingCron)
} }
@ -186,7 +197,7 @@ class CronManager {
// Add to cron or start new cron // Add to cron or start new cron
if (libraryItem.media.autoDownloadEpisodes && libraryItem.media.autoDownloadSchedule) { if (libraryItem.media.autoDownloadEpisodes && libraryItem.media.autoDownloadSchedule) {
const cronMatchingExpression = this.podcastCrons.find(pc => pc.expression === libraryItem.media.autoDownloadSchedule) const cronMatchingExpression = this.podcastCrons.find((pc) => pc.expression === libraryItem.media.autoDownloadSchedule)
if (cronMatchingExpression) { if (cronMatchingExpression) {
cronMatchingExpression.libraryItemIds.push(libraryItem.id) cronMatchingExpression.libraryItemIds.push(libraryItem.id)
Logger.info(`[CronManager] Added podcast "${libraryItem.media.metadata.title}" to auto dl episode cron "${cronMatchingExpression.expression}"`) Logger.info(`[CronManager] Added podcast "${libraryItem.media.metadata.title}" to auto dl episode cron "${cronMatchingExpression.expression}"`)
@ -196,4 +207,4 @@ class CronManager {
} }
} }
} }
module.exports = CronManager module.exports = CronManager