filenotify.go (1583B)
1 // Package filenotify provides a mechanism for watching file(s) for changes.
2 // Generally leans on fsnotify, but provides a poll-based notifier which fsnotify does not support.
3 // These are wrapped up in a common interface so that either can be used interchangeably in your code.
4 //
5 // This package is adapted from https://github.com/moby/moby/tree/master/pkg/filenotify, Apache-2.0 License.
6 // Hopefully this can be replaced with an external package sometime in the future, see https://github.com/fsnotify/fsnotify/issues/9
7 package filenotify
8
9 import (
10 "time"
11
12 "github.com/fsnotify/fsnotify"
13 )
14
15 // FileWatcher is an interface for implementing file notification watchers
16 type FileWatcher interface {
17 Events() <-chan fsnotify.Event
18 Errors() <-chan error
19 Add(name string) error
20 Remove(name string) error
21 Close() error
22 }
23
24 // New tries to use an fs-event watcher, and falls back to the poller if there is an error
25 func New(interval time.Duration) (FileWatcher, error) {
26 if watcher, err := NewEventWatcher(); err == nil {
27 return watcher, nil
28 }
29 return NewPollingWatcher(interval), nil
30 }
31
32 // NewPollingWatcher returns a poll-based file watcher
33 func NewPollingWatcher(interval time.Duration) FileWatcher {
34 return &filePoller{
35 interval: interval,
36 done: make(chan struct{}),
37 events: make(chan fsnotify.Event),
38 errors: make(chan error),
39 }
40 }
41
42 // NewEventWatcher returns an fs-event based file watcher
43 func NewEventWatcher() (FileWatcher, error) {
44 watcher, err := fsnotify.NewWatcher()
45 if err != nil {
46 return nil, err
47 }
48 return &fsNotifyWatcher{watcher}, nil
49 }