github.com/Cloud-Foundations/Dominator@v0.3.4/lib/fsutil/watchFile_linux.go (about)

     1  package fsutil
     2  
     3  import (
     4  	"path"
     5  	"sync"
     6  
     7  	"github.com/Cloud-Foundations/Dominator/lib/log"
     8  	"github.com/fsnotify/fsnotify"
     9  )
    10  
    11  var (
    12  	lock     sync.RWMutex
    13  	watchers []*fsnotify.Watcher
    14  )
    15  
    16  func watchFileWithFsNotify(pathname string, logger log.Logger) <-chan struct{} {
    17  	watcher, err := fsnotify.NewWatcher()
    18  	if err != nil {
    19  		logger.Println("Error creating watcher:", err)
    20  		return nil
    21  	}
    22  	lock.Lock()
    23  	defer lock.Unlock()
    24  	watchers = append(watchers, watcher)
    25  	pathname = path.Clean(pathname)
    26  	dirname := path.Dir(pathname)
    27  	if err := watcher.Add(dirname); err != nil {
    28  		logger.Println("Error adding watch:", err)
    29  		return nil
    30  	}
    31  	channel := make(chan struct{}, 1)
    32  	go waitForNotifyEvents(watcher, pathname, channel, logger)
    33  	return channel
    34  }
    35  
    36  func watchFileStopWithFsNotify() bool {
    37  	lock.Lock()
    38  	defer lock.Unlock()
    39  	// Send cleanup notification to watchers.
    40  	for _, watcher := range watchers {
    41  		watcher.Close()
    42  	}
    43  	// Wait for cleanup of each watcher.
    44  	for _, watcher := range watchers {
    45  		for {
    46  			if _, ok := <-watcher.Events; !ok {
    47  				break
    48  			}
    49  		}
    50  	}
    51  	watchers = nil
    52  	return true
    53  }
    54  
    55  func waitForNotifyEvents(watcher *fsnotify.Watcher, pathname string,
    56  	channel chan<- struct{}, logger log.Logger) {
    57  	for {
    58  		select {
    59  		case event, ok := <-watcher.Events:
    60  			if !ok {
    61  				return
    62  			}
    63  			if path.Clean(event.Name) != pathname {
    64  				continue
    65  			}
    66  			channel <- struct{}{}
    67  		case err, ok := <-watcher.Errors:
    68  			if !ok {
    69  				return
    70  			}
    71  			logger.Println("Error with watcher:", err)
    72  		}
    73  	}
    74  }