go-micro.dev/v5@v5.12.0/config/source/file/watcher_linux.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package file
     5  
     6  import (
     7  	"os"
     8  
     9  	"github.com/fsnotify/fsnotify"
    10  	"go-micro.dev/v5/config/source"
    11  )
    12  
    13  type watcher struct {
    14  	f *file
    15  
    16  	fw *fsnotify.Watcher
    17  }
    18  
    19  func newWatcher(f *file) (source.Watcher, error) {
    20  	fw, err := fsnotify.NewWatcher()
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  
    25  	fw.Add(f.path)
    26  
    27  	return &watcher{
    28  		f:  f,
    29  		fw: fw,
    30  	}, nil
    31  }
    32  
    33  func (w *watcher) Next() (*source.ChangeSet, error) {
    34  	// try get the event
    35  	select {
    36  	case event, ok := <-w.fw.Events:
    37  		// check if channel was closed (i.e. Watcher.Close() was called).
    38  		if !ok {
    39  			return nil, source.ErrWatcherStopped
    40  		}
    41  
    42  		if event.Has(fsnotify.Rename) {
    43  			// check existence of file, and add watch again
    44  			_, err := os.Stat(event.Name)
    45  			if err == nil || os.IsExist(err) {
    46  				w.fw.Add(event.Name)
    47  			}
    48  		}
    49  
    50  		c, err := w.f.Read()
    51  		if err != nil {
    52  			return nil, err
    53  		}
    54  
    55  		// add path again for the event bug of fsnotify
    56  		w.fw.Add(w.f.path)
    57  
    58  		return c, nil
    59  	case err, ok := <-w.fw.Errors:
    60  		// check if channel was closed (i.e. Watcher.Close() was called).
    61  		if !ok {
    62  			return nil, source.ErrWatcherStopped
    63  		}
    64  
    65  		return nil, err
    66  	}
    67  }
    68  
    69  func (w *watcher) Stop() error {
    70  	return w.fw.Close()
    71  }