You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.3 KiB
67 lines
1.3 KiB
package file |
|
|
|
import ( |
|
"context" |
|
"os" |
|
"path/filepath" |
|
|
|
"github.com/fsnotify/fsnotify" |
|
"github.com/go-kratos/kratos/v2/config" |
|
) |
|
|
|
type watcher struct { |
|
f *file |
|
fw *fsnotify.Watcher |
|
|
|
ctx context.Context |
|
cancel context.CancelFunc |
|
} |
|
|
|
var _ config.Watcher = (*watcher)(nil) |
|
|
|
func newWatcher(f *file) (config.Watcher, error) { |
|
fw, err := fsnotify.NewWatcher() |
|
if err != nil { |
|
return nil, err |
|
} |
|
if err := fw.Add(f.path); err != nil { |
|
return nil, err |
|
} |
|
ctx, cancel := context.WithCancel(context.Background()) |
|
return &watcher{f: f, fw: fw, ctx: ctx, cancel: cancel}, nil |
|
} |
|
|
|
func (w *watcher) Next() ([]*config.KeyValue, error) { |
|
select { |
|
case <-w.ctx.Done(): |
|
return nil, w.ctx.Err() |
|
case event := <-w.fw.Events: |
|
if event.Op == fsnotify.Rename { |
|
if _, err := os.Stat(event.Name); err == nil || os.IsExist(err) { |
|
if err := w.fw.Add(event.Name); err != nil { |
|
return nil, err |
|
} |
|
} |
|
} |
|
fi, err := os.Stat(w.f.path) |
|
if err != nil { |
|
return nil, err |
|
} |
|
path := w.f.path |
|
if fi.IsDir() { |
|
path = filepath.Join(w.f.path, filepath.Base(event.Name)) |
|
} |
|
kv, err := w.f.loadFile(path) |
|
if err != nil { |
|
return nil, err |
|
} |
|
return []*config.KeyValue{kv}, nil |
|
case err := <-w.fw.Errors: |
|
return nil, err |
|
} |
|
} |
|
|
|
func (w *watcher) Stop() error { |
|
w.cancel() |
|
return w.fw.Close() |
|
}
|
|
|