package watchers import ( "sync" "time" "Moonshark/core/utils/logger" ) // Default polling interval const ( defaultPollInterval = 1 * time.Second ) // WatcherManager coordinates file watching across multiple directories type WatcherManager struct { watchers map[string]*DirectoryWatcher mu sync.RWMutex done chan struct{} ticker *time.Ticker wg sync.WaitGroup } // NewWatcherManager creates a new watcher manager func NewWatcherManager() *WatcherManager { manager := &WatcherManager{ watchers: make(map[string]*DirectoryWatcher), done: make(chan struct{}), } manager.ticker = time.NewTicker(defaultPollInterval) manager.wg.Add(1) go manager.pollLoop() return manager } // Close stops all watchers and the manager func (m *WatcherManager) Close() error { close(m.done) if m.ticker != nil { m.ticker.Stop() } m.wg.Wait() return nil } // AddWatcher registers a new directory watcher func (m *WatcherManager) AddWatcher(watcher *DirectoryWatcher) { m.mu.Lock() defer m.mu.Unlock() m.watchers[watcher.dir] = watcher logger.Debug("WatcherManager added watcher for %s", watcher.dir) } // RemoveWatcher unregisters a directory watcher func (m *WatcherManager) RemoveWatcher(dir string) { m.mu.Lock() defer m.mu.Unlock() delete(m.watchers, dir) logger.Debug("WatcherManager removed watcher for %s", dir) } // pollLoop is the main polling loop that checks all watched directories func (m *WatcherManager) pollLoop() { defer m.wg.Done() for { select { case <-m.ticker.C: m.checkAllDirectories() case <-m.done: return } } } // checkAllDirectories polls all registered directories for changes func (m *WatcherManager) checkAllDirectories() { m.mu.RLock() defer m.mu.RUnlock() for _, watcher := range m.watchers { changed, err := watcher.checkForChanges() if err != nil { logger.Error("[WatcherManager] Error checking directory %s: %v", watcher.dir, err) continue } if changed { watcher.notifyChange() } } }