forked from spf13/viper
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
viper: support building on AIX (#15)
This commit removes the config watch feature of the library when building on AIX. The fsnotify dependency required for this feature does not currently compile on AIX, and we no not currently need this feature on AIX.
- Loading branch information
Showing
2 changed files
with
81 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// +build !aix | ||
|
||
package viper | ||
|
||
import ( | ||
"log" | ||
"path/filepath" | ||
"sync" | ||
|
||
"github.com/fsnotify/fsnotify" | ||
) | ||
|
||
func WatchConfig() { v.WatchConfig() } | ||
|
||
func (v *Viper) WatchConfig() { | ||
initWG := sync.WaitGroup{} | ||
initWG.Add(1) | ||
go func() { | ||
watcher, err := fsnotify.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 | ||
filename, err := v.getConfigFile() | ||
if err != nil { | ||
log.Printf("error: %v\n", err) | ||
return | ||
} | ||
|
||
configFile := filepath.Clean(filename) | ||
configDir, _ := filepath.Split(configFile) | ||
realConfigFile, _ := filepath.EvalSymlinks(filename) | ||
|
||
eventsWG := sync.WaitGroup{} | ||
eventsWG.Add(1) | ||
go func() { | ||
for { | ||
select { | ||
case event, ok := <-watcher.Events: | ||
if !ok { // 'Events' channel is closed | ||
eventsWG.Done() | ||
return | ||
} | ||
currentConfigFile, _ := filepath.EvalSymlinks(filename) | ||
// we only care about the config file with the following cases: | ||
// 1 - if the config file was modified or created | ||
// 2 - if the real path to the config file changed (eg: k8s ConfigMap replacement) | ||
const writeOrCreateMask = fsnotify.Write | fsnotify.Create | ||
if (filepath.Clean(event.Name) == configFile && | ||
event.Op&writeOrCreateMask != 0) || | ||
(currentConfigFile != "" && currentConfigFile != realConfigFile) { | ||
realConfigFile = currentConfigFile | ||
err := v.ReadInConfig() | ||
if err != nil { | ||
log.Printf("error reading config file: %v\n", err) | ||
} | ||
if v.onConfigChange != nil { | ||
v.onConfigChange(event) | ||
} | ||
} else if filepath.Clean(event.Name) == configFile && | ||
event.Op&fsnotify.Remove&fsnotify.Remove != 0 { | ||
eventsWG.Done() | ||
return | ||
} | ||
|
||
case err, ok := <-watcher.Errors: | ||
if ok { // 'Errors' channel is not closed | ||
log.Printf("watcher error: %v\n", err) | ||
} | ||
eventsWG.Done() | ||
return | ||
} | ||
} | ||
}() | ||
watcher.Add(configDir) | ||
initWG.Done() // done initalizing 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 | ||
} |