Update watcher scanner to show task notification

This commit is contained in:
advplyr 2023-10-21 12:25:45 -05:00
parent bef6549805
commit d7264f8c22
3 changed files with 53 additions and 8 deletions

View File

@ -125,7 +125,7 @@ export default {
this.$store this.$store
.dispatch('libraries/requestLibraryScan', { libraryId: this.library.id, force }) .dispatch('libraries/requestLibraryScan', { libraryId: this.library.id, force })
.then(() => { .then(() => {
this.$toast.success(this.$strings.ToastLibraryScanStarted) // this.$toast.success(this.$strings.ToastLibraryScanStarted)
}) })
.catch((error) => { .catch((error) => {
console.error('Failed to start scan', error) console.error('Failed to start scan', error)

View File

@ -3,6 +3,8 @@ const EventEmitter = require('events')
const Watcher = require('./libs/watcher/watcher') const Watcher = require('./libs/watcher/watcher')
const Logger = require('./Logger') const Logger = require('./Logger')
const LibraryScanner = require('./scanner/LibraryScanner') const LibraryScanner = require('./scanner/LibraryScanner')
const Task = require('./objects/Task')
const TaskManager = require('./managers/TaskManager')
const { filePathToPOSIX } = require('./utils/fileUtils') const { filePathToPOSIX } = require('./utils/fileUtils')
@ -22,7 +24,10 @@ class FolderWatcher extends EventEmitter {
/** @type {PendingFileUpdate[]} */ /** @type {PendingFileUpdate[]} */
this.pendingFileUpdates = [] this.pendingFileUpdates = []
this.pendingDelay = 4000 this.pendingDelay = 4000
/** @type {NodeJS.Timeout} */
this.pendingTimeout = null this.pendingTimeout = null
/** @type {Task} */
this.pendingTask = null
/** @type {string[]} */ /** @type {string[]} */
this.ignoreDirs = [] this.ignoreDirs = []
@ -202,6 +207,13 @@ class FolderWatcher extends EventEmitter {
Logger.debug(`[Watcher] Modified file in library "${libwatcher.name}" and folder "${folder.id}" with relPath "${relPath}"`) Logger.debug(`[Watcher] Modified file in library "${libwatcher.name}" and folder "${folder.id}" with relPath "${relPath}"`)
if (!this.pendingTask) {
const taskData = {
libraryId,
libraryName: libwatcher.name
}
this.pendingTask = TaskManager.createAndAddTask('watcher-scan', `Scanning file changes in "${libwatcher.name}"`, null, true, taskData)
}
this.pendingFileUpdates.push({ this.pendingFileUpdates.push({
path, path,
relPath, relPath,
@ -213,8 +225,8 @@ class FolderWatcher extends EventEmitter {
// Notify server of update after "pendingDelay" // Notify server of update after "pendingDelay"
clearTimeout(this.pendingTimeout) clearTimeout(this.pendingTimeout)
this.pendingTimeout = setTimeout(() => { this.pendingTimeout = setTimeout(() => {
// this.emit('files', this.pendingFileUpdates) LibraryScanner.scanFilesChanged(this.pendingFileUpdates, this.pendingTask)
LibraryScanner.scanFilesChanged(this.pendingFileUpdates) this.pendingTask = null
this.pendingFileUpdates = [] this.pendingFileUpdates = []
}, this.pendingDelay) }, this.pendingDelay)
} }

View File

@ -13,6 +13,7 @@ const TaskManager = require('../managers/TaskManager')
const LibraryItemScanner = require('./LibraryItemScanner') const LibraryItemScanner = require('./LibraryItemScanner')
const LibraryScan = require('./LibraryScan') const LibraryScan = require('./LibraryScan')
const LibraryItemScanData = require('./LibraryItemScanData') const LibraryItemScanData = require('./LibraryItemScanData')
const Task = require('../objects/Task')
class LibraryScanner { class LibraryScanner {
constructor() { constructor() {
@ -20,7 +21,7 @@ class LibraryScanner {
this.librariesScanning = [] this.librariesScanning = []
this.scanningFilesChanged = false this.scanningFilesChanged = false
/** @type {import('../Watcher').PendingFileUpdate[][]} */ /** @type {[import('../Watcher').PendingFileUpdate[], Task][]} */
this.pendingFileUpdatesToScan = [] this.pendingFileUpdatesToScan = []
} }
@ -335,18 +336,25 @@ class LibraryScanner {
/** /**
* Scan files changed from Watcher * Scan files changed from Watcher
* @param {import('../Watcher').PendingFileUpdate[]} fileUpdates * @param {import('../Watcher').PendingFileUpdate[]} fileUpdates
* @param {Task} pendingTask
*/ */
async scanFilesChanged(fileUpdates) { async scanFilesChanged(fileUpdates, pendingTask) {
if (!fileUpdates?.length) return if (!fileUpdates?.length) return
// If already scanning files from watcher then add these updates to queue // If already scanning files from watcher then add these updates to queue
if (this.scanningFilesChanged) { if (this.scanningFilesChanged) {
this.pendingFileUpdatesToScan.push(fileUpdates) this.pendingFileUpdatesToScan.push([fileUpdates, pendingTask])
Logger.debug(`[LibraryScanner] Already scanning files from watcher - file updates pushed to queue (size ${this.pendingFileUpdatesToScan.length})`) Logger.debug(`[LibraryScanner] Already scanning files from watcher - file updates pushed to queue (size ${this.pendingFileUpdatesToScan.length})`)
return return
} }
this.scanningFilesChanged = true this.scanningFilesChanged = true
const results = {
added: 0,
updated: 0,
removed: 0
}
// files grouped by folder // files grouped by folder
const folderGroups = this.getFileUpdatesGrouped(fileUpdates) const folderGroups = this.getFileUpdatesGrouped(fileUpdates)
@ -377,17 +385,42 @@ class LibraryScanner {
const folderScanResults = await this.scanFolderUpdates(library, folder, fileUpdateGroup) const folderScanResults = await this.scanFolderUpdates(library, folder, fileUpdateGroup)
Logger.debug(`[LibraryScanner] Folder scan results`, folderScanResults) Logger.debug(`[LibraryScanner] Folder scan results`, folderScanResults)
// Tally results to share with client
let resetFilterData = false
Object.values(folderScanResults).forEach((scanResult) => {
if (scanResult === ScanResult.ADDED) {
resetFilterData = true
results.added++
} else if (scanResult === ScanResult.REMOVED) {
resetFilterData = true
results.removed++
} else if (scanResult === ScanResult.UPDATED) {
resetFilterData = true
results.updated++
}
})
// If something was updated then reset numIssues filter data for library // If something was updated then reset numIssues filter data for library
if (Object.values(folderScanResults).some(scanResult => scanResult !== ScanResult.NOTHING && scanResult !== ScanResult.UPTODATE)) { if (resetFilterData) {
await Database.resetLibraryIssuesFilterData(libraryId) await Database.resetLibraryIssuesFilterData(libraryId)
} }
} }
// Complete task and send results to client
const resultStrs = []
if (results.added) resultStrs.push(`${results.added} added`)
if (results.updated) resultStrs.push(`${results.updated} updated`)
if (results.removed) resultStrs.push(`${results.removed} missing`)
let scanResultStr = 'Scan finished with no changes'
if (resultStrs.length) scanResultStr = resultStrs.join(', ')
pendingTask.setFinished(scanResultStr)
TaskManager.taskFinished(pendingTask)
this.scanningFilesChanged = false this.scanningFilesChanged = false
if (this.pendingFileUpdatesToScan.length) { if (this.pendingFileUpdatesToScan.length) {
Logger.debug(`[LibraryScanner] File updates finished scanning with more updates in queue (${this.pendingFileUpdatesToScan.length})`) Logger.debug(`[LibraryScanner] File updates finished scanning with more updates in queue (${this.pendingFileUpdatesToScan.length})`)
this.scanFilesChanged(this.pendingFileUpdatesToScan.shift()) this.scanFilesChanged(...this.pendingFileUpdatesToScan.shift())
} }
} }