filebrowser/backend/files/indexingSchedule.go

127 lines
3.9 KiB
Go
Raw Normal View History

2024-11-26 17:21:41 +00:00
package files
import (
2025-01-21 14:02:43 +00:00
"fmt"
2024-11-26 17:21:41 +00:00
"time"
2025-01-21 14:02:43 +00:00
"github.com/gtsteffaniak/filebrowser/backend/logger"
2024-11-26 17:21:41 +00:00
)
// schedule in minutes
var scanSchedule = []time.Duration{
5 * time.Minute, // 5 minute quick scan & 25 minutes for a full scan
10 * time.Minute,
20 * time.Minute, // [3] element is 20 minutes, reset anchor for full scan
40 * time.Minute,
1 * time.Hour,
2 * time.Hour,
3 * time.Hour,
4 * time.Hour, // 4 hours for quick scan & 20 hours for a full scan
}
2025-01-05 19:05:33 +00:00
func (idx *Index) newScanner(origin string) {
2024-11-26 17:21:41 +00:00
fullScanAnchor := 3
fullScanCounter := 0 // every 5th scan is a full scan
for {
// Determine sleep time with modifiers
fullScanCounter++
2025-01-05 19:05:33 +00:00
sleepTime := scanSchedule[idx.currentSchedule] + idx.SmartModifier
if idx.assessment == "simple" {
sleepTime = scanSchedule[idx.currentSchedule] - idx.SmartModifier
2024-11-26 17:21:41 +00:00
}
2025-01-05 19:05:33 +00:00
if idx.Source.Config.IndexingInterval > 0 {
sleepTime = time.Duration(idx.Source.Config.IndexingInterval) * time.Minute
2024-11-26 17:21:41 +00:00
}
// Log and sleep before indexing
2025-01-26 00:31:40 +00:00
logger.Debug(fmt.Sprintf("Next scan in %v", sleepTime))
2024-11-26 17:21:41 +00:00
time.Sleep(sleepTime)
2025-01-05 19:05:33 +00:00
idx.scannerMu.Lock()
2024-11-26 17:21:41 +00:00
if fullScanCounter == 5 {
2025-01-05 19:05:33 +00:00
idx.RunIndexing(origin, false) // Full scan
2024-11-26 17:21:41 +00:00
fullScanCounter = 0
} else {
2025-01-05 19:05:33 +00:00
idx.RunIndexing(origin, true) // Quick scan
2024-11-26 17:21:41 +00:00
}
2025-01-05 19:05:33 +00:00
idx.scannerMu.Unlock()
2024-11-26 17:21:41 +00:00
// Adjust schedule based on file changes
2025-01-05 19:05:33 +00:00
if idx.FilesChangedDuringIndexing {
2024-11-26 17:21:41 +00:00
// Move to at least the full-scan anchor or reduce interval
2025-01-05 19:05:33 +00:00
if idx.currentSchedule > fullScanAnchor {
idx.currentSchedule = fullScanAnchor
} else if idx.currentSchedule > 0 {
idx.currentSchedule--
2024-11-26 17:21:41 +00:00
}
} else {
// Increment toward the longest interval if no changes
2025-01-05 19:05:33 +00:00
if idx.currentSchedule < len(scanSchedule)-1 {
idx.currentSchedule++
2024-11-26 17:21:41 +00:00
}
}
2025-01-05 19:05:33 +00:00
if idx.assessment == "simple" && idx.currentSchedule > 3 {
idx.currentSchedule = 3
2024-11-26 17:21:41 +00:00
}
// Ensure `currentSchedule` stays within bounds
2025-01-05 19:05:33 +00:00
if idx.currentSchedule < 0 {
idx.currentSchedule = 0
} else if idx.currentSchedule >= len(scanSchedule) {
idx.currentSchedule = len(scanSchedule) - 1
2024-11-26 17:21:41 +00:00
}
}
}
2025-01-05 19:05:33 +00:00
func (idx *Index) RunIndexing(origin string, quick bool) {
prevNumDirs := idx.NumDirs
prevNumFiles := idx.NumFiles
2024-11-26 17:21:41 +00:00
if quick {
2025-02-16 14:07:38 +00:00
logger.Debug(fmt.Sprintf("Starting quick scan for [%v]", idx.Source.Name))
2024-11-26 17:21:41 +00:00
} else {
2025-02-16 14:07:38 +00:00
logger.Debug(fmt.Sprintf("Starting full scan for [%v]", idx.Source.Name))
2025-01-05 19:05:33 +00:00
idx.NumDirs = 0
idx.NumFiles = 0
2024-11-26 17:21:41 +00:00
}
startTime := time.Now()
2025-01-05 19:05:33 +00:00
idx.FilesChangedDuringIndexing = false
2024-11-26 17:21:41 +00:00
// Perform the indexing operation
2025-01-05 19:05:33 +00:00
err := idx.indexDirectory("/", quick, true)
2024-11-26 17:21:41 +00:00
if err != nil {
2025-01-21 14:02:43 +00:00
logger.Error(fmt.Sprintf("Error during indexing: %v", err))
2024-11-26 17:21:41 +00:00
}
2025-01-21 14:02:43 +00:00
firstRun := idx.LastIndexed == time.Time{}
2024-11-26 17:21:41 +00:00
// Update the LastIndexed time
2025-01-05 19:05:33 +00:00
idx.LastIndexed = time.Now()
idx.indexingTime = int(time.Since(startTime).Seconds())
2024-11-26 17:21:41 +00:00
if !quick {
// update smart indexing
2025-01-05 19:05:33 +00:00
if idx.indexingTime < 3 || idx.NumDirs < 10000 {
idx.assessment = "simple"
idx.SmartModifier = 4 * time.Minute
} else if idx.indexingTime > 120 || idx.NumDirs > 500000 {
idx.assessment = "complex"
modifier := idx.indexingTime / 10 // seconds
idx.SmartModifier = time.Duration(modifier) * time.Minute
2024-11-26 17:21:41 +00:00
} else {
2025-01-05 19:05:33 +00:00
idx.assessment = "normal"
2024-11-26 17:21:41 +00:00
}
2025-01-21 14:02:43 +00:00
if firstRun {
2025-02-16 14:07:38 +00:00
logger.Info(fmt.Sprintf("Index assessment : index=%v complexity=%v directories=%v files=%v", idx.Source.Name, idx.assessment, idx.NumDirs, idx.NumFiles))
2025-01-21 14:02:43 +00:00
} else {
2025-02-16 14:07:38 +00:00
logger.Debug(fmt.Sprintf("Index assessment : iindex=%v complexity=%v directories=%v files=%v", idx.Source.Name, idx.assessment, idx.NumDirs, idx.NumFiles))
2025-01-21 14:02:43 +00:00
}
2025-01-05 19:05:33 +00:00
if idx.NumDirs != prevNumDirs || idx.NumFiles != prevNumFiles {
idx.FilesChangedDuringIndexing = true
2024-11-26 17:21:41 +00:00
}
}
2025-01-21 14:02:43 +00:00
if firstRun {
2025-02-16 14:07:38 +00:00
logger.Info(fmt.Sprintf("Time spent indexing [%v]: %v seconds", idx.Source.Name, idx.indexingTime))
2025-01-21 14:02:43 +00:00
} else {
2025-02-16 14:07:38 +00:00
logger.Debug(fmt.Sprintf("Time spent indexing [%v]: %v seconds", idx.Source.Name, idx.indexingTime))
2025-01-21 14:02:43 +00:00
}
2024-11-26 17:21:41 +00:00
}
2025-01-05 19:05:33 +00:00
func (idx *Index) setupIndexingScanners() {
go idx.newScanner("/")
2024-11-26 17:21:41 +00:00
}