micro/config/source/file/watcher.go

78 lines
1.4 KiB
Go
Raw Normal View History

//+build !linux
2019-05-30 23:11:13 +01:00
package file
import (
"os"
"github.com/fsnotify/fsnotify"
"github.com/unistack-org/micro/v3/config/source"
2019-05-30 23:11:13 +01:00
)
type watcher struct {
f *file
fw *fsnotify.Watcher
exit chan bool
}
func newWatcher(f *file) (source.Watcher, error) {
fw, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
fw.Add(f.path)
return &watcher{
f: f,
fw: fw,
exit: make(chan bool),
}, nil
}
func (w *watcher) Next() (*source.ChangeSet, error) {
// is it closed?
select {
case <-w.exit:
return nil, source.ErrWatcherStopped
2019-05-30 23:11:13 +01:00
default:
}
for {
// try get the event
select {
case event, _ := <-w.fw.Events:
if event.Op == fsnotify.Rename {
// check existence of file, and add watch again
_, err := os.Stat(event.Name)
if err == nil || os.IsExist(err) {
w.fw.Add(event.Name)
}
}
// ARCH: Darwin Kernel Version 18.7.0
// ioutil.WriteFile truncates it before writing, but the problem is that
// you will receive two events(fsnotify.Chmod and fsnotify.Write).
// We can solve this problem by ignoring fsnotify.Chmod event.
if event.Op&fsnotify.Write != fsnotify.Write {
continue
2019-05-30 23:11:13 +01:00
}
c, err := w.f.Read()
if err != nil {
return nil, err
}
return c, nil
case err := <-w.fw.Errors:
2019-05-30 23:11:13 +01:00
return nil, err
case <-w.exit:
return nil, source.ErrWatcherStopped
2019-05-30 23:11:13 +01:00
}
}
}
func (w *watcher) Stop() error {
return w.fw.Close()
}