99 lines
2.0 KiB
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()
|
|
}
|
|
}
|
|
}
|