mirror of https://github.com/spf13/viper.git
Avoid having 2 goroutines to handle file changes
On goroutine was just waiting the goroutine handing the events just to keep the "watcher" variable alive. Move defer to event handling goroutine and avoid one goroutine. Signed-off-by: Frediano Ziglio <fziglio@cyral.com>
This commit is contained in:
parent
24f5069098
commit
ab4327a019
26
viper.go
26
viper.go
|
@ -32,7 +32,6 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/fsnotify/fsnotify"
|
"github.com/fsnotify/fsnotify"
|
||||||
|
@ -341,19 +340,10 @@ func (v *Viper) OnConfigChange(run func(in fsnotify.Event)) {
|
||||||
func WatchConfig() { v.WatchConfig() }
|
func WatchConfig() { v.WatchConfig() }
|
||||||
|
|
||||||
func (v *Viper) WatchConfig() {
|
func (v *Viper) WatchConfig() {
|
||||||
initWG := sync.WaitGroup{}
|
|
||||||
initWG.Add(1)
|
|
||||||
go func() {
|
|
||||||
watcher, err := newWatcher()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer watcher.Close()
|
|
||||||
// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
|
// we have to watch the entire directory to pick up renames/atomic saves in a cross-platform way
|
||||||
filename, err := v.getConfigFile()
|
filename, err := v.getConfigFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error: %v\n", err)
|
log.Printf("error: %v\n", err)
|
||||||
initWG.Done()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,14 +351,18 @@ func (v *Viper) WatchConfig() {
|
||||||
configDir, _ := filepath.Split(configFile)
|
configDir, _ := filepath.Split(configFile)
|
||||||
realConfigFile, _ := filepath.EvalSymlinks(filename)
|
realConfigFile, _ := filepath.EvalSymlinks(filename)
|
||||||
|
|
||||||
eventsWG := sync.WaitGroup{}
|
watcher, err := newWatcher()
|
||||||
eventsWG.Add(1)
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
defer watcher.Close()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case event, ok := <-watcher.Events:
|
case event, ok := <-watcher.Events:
|
||||||
if !ok { // 'Events' channel is closed
|
if !ok { // 'Events' channel is closed
|
||||||
eventsWG.Done()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
currentConfigFile, _ := filepath.EvalSymlinks(filename)
|
currentConfigFile, _ := filepath.EvalSymlinks(filename)
|
||||||
|
@ -389,7 +383,6 @@ func (v *Viper) WatchConfig() {
|
||||||
}
|
}
|
||||||
} else if filepath.Clean(event.Name) == configFile &&
|
} else if filepath.Clean(event.Name) == configFile &&
|
||||||
event.Op&fsnotify.Remove != 0 {
|
event.Op&fsnotify.Remove != 0 {
|
||||||
eventsWG.Done()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,16 +390,11 @@ func (v *Viper) WatchConfig() {
|
||||||
if ok { // 'Errors' channel is not closed
|
if ok { // 'Errors' channel is not closed
|
||||||
log.Printf("watcher error: %v\n", err)
|
log.Printf("watcher error: %v\n", err)
|
||||||
}
|
}
|
||||||
eventsWG.Done()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
watcher.Add(configDir)
|
watcher.Add(configDir)
|
||||||
initWG.Done() // done initializing the watch in this go routine, so the parent routine can move on...
|
|
||||||
eventsWG.Wait() // now, wait for event loop to end in this go-routine...
|
|
||||||
}()
|
|
||||||
initWG.Wait() // make sure that the go routine above fully ended before returning
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetConfigFile explicitly defines the path, name and extension of the config file.
|
// SetConfigFile explicitly defines the path, name and extension of the config file.
|
||||||
|
|
Loading…
Reference in New Issue