feat(scanner): convert scan poll interval from minutes to seconds

- Rename SCAN_POLL_INTERVAL_MINUTES to SCAN_POLL_INTERVAL_SECONDS in config
- Update MediaScanner to accept interval in seconds instead of minutes
- Adjust default polling interval from 3 minutes to 30 seconds for faster response
- Add debug logging for fsnotify events to aid troubleshooting file watching

This change improves media file detection responsiveness by reducing the
polling interval from minutes to seconds, while maintaining the file
watcher as the primary detection mechanism.
This commit is contained in:
2026-02-28 01:59:35 -05:00
parent 037e7c1189
commit 286d0b5e06
4 changed files with 10 additions and 7 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ services:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${DBPASS}
COOKIE_SECURE: false # make true in production with HTTPS
SCAN_POLL_INTERVAL_MINUTES: 3
SCAN_POLL_INTERVAL_SECONDS: 30
volumes:
- postgres_data:/var/lib/postgresql/data
- ./database/schema:/docker-entrypoint-initdb.d
+2 -2
View File
@@ -19,7 +19,7 @@ type Config struct {
TestMode bool
RateLimitEnabled bool
RequestsPerMinute int
ScanPollIntervalMinutes int `env:"SCAN_POLL_INTERVAL_MINUTES" default:"3"`
ScanPollIntervalSeconds int `env:"SCAN_POLL_INTERVAL_SECONDS" default:"30"`
}
func LoadConfig() *Config {
@@ -37,7 +37,7 @@ func LoadConfig() *Config {
TestMode: getEnvBool("TEST_MODE", false),
RateLimitEnabled: getEnvBool("RATE_LIMIT_ENABLED", true),
RequestsPerMinute: getEnvInt("REQUESTS_PER_MINUTE", 10),
ScanPollIntervalMinutes: getEnvInt("SCAN_POLL_INTERVAL_MINUTES", 3),
ScanPollIntervalSeconds: getEnvInt("SCAN_POLL_INTERVAL_SECONDS", 30),
}
}
+1 -1
View File
@@ -42,7 +42,7 @@ func NewHandler(db *database.Queries, connManager *wsync.ConnectionManager, queu
return &Handler{
db: db,
scanner: services.NewMediaScanner(db, cfg.ScanPollIntervalMinutes),
scanner: services.NewMediaScanner(db, cfg.ScanPollIntervalSeconds),
worker: worker,
scheduler: scheduler,
queueProcessor: queueProcessor,
+6 -3
View File
@@ -90,15 +90,16 @@ type MediaScanner struct {
}
// NewMediaScanner creates a new media scanner instance
func NewMediaScanner(db *database.Queries, pollIntervalMinutes int) *MediaScanner {
func NewMediaScanner(db *database.Queries, pollIntervalSeconds int) *MediaScanner {
watcher, err := fsnotify.NewWatcher()
if err != nil {
panic(fmt.Sprintf("Failed to create file watcher: %v", err))
}
pollInterval := 3 * time.Minute
pollInterval := 30 * time.Second
if pollInterval > 0 {
pollInterval = time.Duration(pollIntervalMinutes) * time.Minute
pollInterval = time.Duration(pollIntervalSeconds) * time.Second
}
return &MediaScanner{
@@ -1523,6 +1524,7 @@ func (s *MediaScanner) WatchChanges(ctx context.Context) {
if !ok {
return
}
fmt.Printf("[FSNOTIFY] Event: %s %s\n", event.Name, event.Op.String())
// Handle new directories - add them to the watcher
if event.Has(fsnotify.Create) {
info, err := os.Stat(event.Name)
@@ -1536,6 +1538,7 @@ func (s *MediaScanner) WatchChanges(ctx context.Context) {
}
// Queue file events for debounced processing
if (event.Has(fsnotify.Create) || event.Has(fsnotify.Write) || event.Has(fsnotify.Remove)) && s.isScannableFile(event.Name) {
fmt.Printf("[FSNOTIFY] Queuing scannable file: %s\n", event.Name)
select {
case s.eventQueue <- event.Name:
// Event queued