newConfigWatcher creates a configWatcher and starts its event loop. Sync registers the actual paths to watch. The watcher does nothing until Sync is called.
( logger slog.Logger, clock quartz.Clock, debounce time.Duration, onChange func(), )
| 55 | // loop. Sync registers the actual paths to watch. The watcher does |
| 56 | // nothing until Sync is called. |
| 57 | func newConfigWatcher( |
| 58 | logger slog.Logger, |
| 59 | clock quartz.Clock, |
| 60 | debounce time.Duration, |
| 61 | onChange func(), |
| 62 | ) (*configWatcher, error) { |
| 63 | if onChange == nil { |
| 64 | return nil, xerrors.New("onChange callback is required") |
| 65 | } |
| 66 | if debounce <= 0 { |
| 67 | debounce = defaultWatchDebounce |
| 68 | } |
| 69 | |
| 70 | w, err := fsnotify.NewWatcher() |
| 71 | if err != nil { |
| 72 | return nil, xerrors.Errorf("create fsnotify watcher: %w", err) |
| 73 | } |
| 74 | |
| 75 | cw := &configWatcher{ |
| 76 | logger: logger, |
| 77 | clock: clock, |
| 78 | debounce: debounce, |
| 79 | onChange: onChange, |
| 80 | watcher: w, |
| 81 | files: make(map[string]string), |
| 82 | dirs: make(map[string]int), |
| 83 | closedCh: make(chan struct{}), |
| 84 | runDoneCh: make(chan struct{}), |
| 85 | } |
| 86 | go cw.run() |
| 87 | return cw, nil |
| 88 | } |
| 89 | |
| 90 | // Sync replaces the watched set with paths. Files no longer in the |
| 91 | // list are removed; new files are added. Symlinks are resolved |