Moonshark/core/watchers/Manager.go

99 lines
2.0 KiB
Go

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()
}
}
}