github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/filemonitor/watcher.go (about) 1 package filemonitor 2 3 import ( 4 "context" 5 6 "github.com/fsnotify/fsnotify" 7 "github.com/sirupsen/logrus" 8 ) 9 10 type watcher struct { 11 notify *fsnotify.Watcher 12 pathsToWatch []string 13 logger logrus.FieldLogger 14 onUpdateFn func(logrus.FieldLogger, fsnotify.Event) 15 } 16 17 // NewWatch sets up monitoring on a slice of paths and will execute the update function to process each event 18 func NewWatch(logger logrus.FieldLogger, pathsToWatch []string, onUpdateFn func(logrus.FieldLogger, fsnotify.Event)) (*watcher, error) { 19 notify, err := fsnotify.NewWatcher() 20 if err != nil { 21 return nil, err 22 } 23 24 for _, item := range pathsToWatch { 25 // (non-recursive if a directory is added) 26 if err := notify.Add(item); err != nil { 27 return nil, err 28 } 29 logger.Debugf("monitoring path '%v'", item) 30 } 31 32 newWatcher := &watcher{ 33 notify: notify, 34 pathsToWatch: pathsToWatch, 35 onUpdateFn: onUpdateFn, 36 logger: logger, 37 } 38 39 return newWatcher, nil 40 } 41 42 func (w *watcher) Run(ctx context.Context) { 43 go func(ctx context.Context) { 44 for { 45 select { 46 case <-ctx.Done(): 47 w.notify.Close() // always returns nil for the error 48 w.logger.Debug("terminating watcher") 49 return 50 case event := <-w.notify.Events: 51 w.logger.Debugf("watcher got event: %v", event) 52 if w.onUpdateFn != nil { 53 w.onUpdateFn(w.logger, event) 54 } 55 case err := <-w.notify.Errors: 56 w.logger.Warnf("watcher got error: %v", err) 57 } 58 } 59 }(ctx) 60 }