|
|
|
|
@ -2,11 +2,17 @@ package confwatcher
@@ -2,11 +2,17 @@ package confwatcher
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"os" |
|
|
|
|
"path/filepath" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"github.com/fsnotify/fsnotify" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
minInterval = 1 * time.Second |
|
|
|
|
additionalWait = 10 * time.Millisecond |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// ConfWatcher is a configuration file watcher.
|
|
|
|
|
type ConfWatcher struct { |
|
|
|
|
inner *fsnotify.Watcher |
|
|
|
|
@ -24,7 +30,10 @@ func New(confPath string) (*ConfWatcher, error) {
@@ -24,7 +30,10 @@ func New(confPath string) (*ConfWatcher, error) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if _, err := os.Stat(confPath); err == nil { |
|
|
|
|
err := inner.Add(confPath) |
|
|
|
|
// use absolute path to support Darwin
|
|
|
|
|
absolutePath, _ := filepath.Abs(confPath) |
|
|
|
|
|
|
|
|
|
err := inner.Add(absolutePath) |
|
|
|
|
if err != nil { |
|
|
|
|
inner.Close() |
|
|
|
|
return nil, err |
|
|
|
|
@ -54,13 +63,22 @@ func (w *ConfWatcher) Close() {
@@ -54,13 +63,22 @@ func (w *ConfWatcher) Close() {
|
|
|
|
|
func (w *ConfWatcher) run() { |
|
|
|
|
defer close(w.done) |
|
|
|
|
|
|
|
|
|
var lastCalled time.Time |
|
|
|
|
|
|
|
|
|
outer: |
|
|
|
|
for { |
|
|
|
|
select { |
|
|
|
|
case event := <-w.inner.Events: |
|
|
|
|
if (event.Op & fsnotify.Write) == fsnotify.Write { |
|
|
|
|
// wait some additional time to avoid EOF
|
|
|
|
|
time.Sleep(10 * time.Millisecond) |
|
|
|
|
if time.Since(lastCalled) < minInterval { |
|
|
|
|
continue |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (event.Op&fsnotify.Write) == fsnotify.Write || |
|
|
|
|
(event.Op&fsnotify.Create) == fsnotify.Create { |
|
|
|
|
// wait some additional time to allow the writer to complete its job
|
|
|
|
|
time.Sleep(additionalWait) |
|
|
|
|
|
|
|
|
|
lastCalled = time.Now() |
|
|
|
|
w.signal <- struct{}{} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -72,7 +90,7 @@ outer:
@@ -72,7 +90,7 @@ outer:
|
|
|
|
|
close(w.signal) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Watch returns when the configuration file has changed.
|
|
|
|
|
// Watch returns a channel that is called when the configuration file has changed.
|
|
|
|
|
func (w *ConfWatcher) Watch() chan struct{} { |
|
|
|
|
return w.signal |
|
|
|
|
} |
|
|
|
|
|