mirror of
https://github.com/spf13/viper
synced 2024-12-23 12:07:02 +00:00
Implement CancelWatchConfig which allows one to turn off the watcher
This commit is contained in:
parent
62edee3196
commit
c3ab84f775
3 changed files with 59 additions and 0 deletions
|
@ -123,6 +123,9 @@ viper.OnConfigChange(func(e fsnotify.Event) {
|
|||
})
|
||||
```
|
||||
|
||||
If you wish to stop watching the configPaths, simply call viper.CancelWatchConfig().
|
||||
Note: This might be necessary if your tests involve trying out various config files.
|
||||
|
||||
### Reading Config from io.Reader
|
||||
|
||||
Viper predefines many configuration sources such as files, environment
|
||||
|
|
18
viper.go
18
viper.go
|
@ -202,6 +202,7 @@ type Viper struct {
|
|||
properties *properties.Properties
|
||||
|
||||
onConfigChange func(fsnotify.Event)
|
||||
watchConfigCancel func() (waiter func())
|
||||
}
|
||||
|
||||
// New returns an initialized Viper instance.
|
||||
|
@ -300,6 +301,13 @@ func (v *Viper) WatchConfig() {
|
|||
|
||||
eventsWG := sync.WaitGroup{}
|
||||
eventsWG.Add(1)
|
||||
v.watchConfigCancel = func() (waiter func()) {
|
||||
watcher.Close()
|
||||
v.watchConfigCancel = nil
|
||||
return func() {
|
||||
eventsWG.Wait()
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
|
@ -346,6 +354,16 @@ func (v *Viper) WatchConfig() {
|
|||
initWG.Wait() // make sure that the go routine above fully ended before returning
|
||||
}
|
||||
|
||||
func CancelWatchConfig() (future func()) {
|
||||
return v.CancelWatchConfig()
|
||||
}
|
||||
func (v *Viper) CancelWatchConfig() (future func()) {
|
||||
if v.watchConfigCancel != nil {
|
||||
return v.watchConfigCancel()
|
||||
}
|
||||
return func(){}
|
||||
}
|
||||
|
||||
// SetConfigFile explicitly defines the path, name and extension of the config file.
|
||||
// Viper will use this and not check any of the config paths.
|
||||
func SetConfigFile(in string) { v.SetConfigFile(in) }
|
||||
|
|
|
@ -1510,6 +1510,44 @@ func TestWatchFile(t *testing.T) {
|
|||
assert.Equal(t, "baz", v.Get("foo"))
|
||||
})
|
||||
|
||||
t.Run("file content changed after cancel", func(t *testing.T) {
|
||||
// given a `config.yaml` file being watched
|
||||
v, configFile, cleanup := newViperWithConfigFile(t)
|
||||
defer cleanup()
|
||||
_, err := os.Stat(configFile)
|
||||
require.NoError(t, err)
|
||||
t.Logf("test config file: %s\n", configFile)
|
||||
|
||||
// first run through with watching enabled
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
v.OnConfigChange(func(in fsnotify.Event) {
|
||||
t.Logf("WatchConfig saw first config change")
|
||||
wg.Done()
|
||||
})
|
||||
v.WatchConfig()
|
||||
// when overwriting the file and waiting for the custom change notification handler to be triggered
|
||||
err = ioutil.WriteFile(configFile, []byte("foo: baz\n"), 0640)
|
||||
wg.Wait()
|
||||
// then the config value should have changed
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "baz", v.Get("foo"))
|
||||
|
||||
// cancel and wait for the canceling to finish.
|
||||
waitForCancel := v.CancelWatchConfig()
|
||||
v.OnConfigChange(func(in fsnotify.Event) {
|
||||
t.Error("CancelWatchConfig did not prevent second change from being seen.")
|
||||
})
|
||||
waitForCancel()
|
||||
|
||||
err = ioutil.WriteFile(configFile, []byte("foo: quz\n"), 0640)
|
||||
// We need to sleep a bit here because there isn't any signal of use for this invisible write.
|
||||
time.Sleep(30 * time.Millisecond)
|
||||
|
||||
// the config value should still be the same.
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "baz", v.Get("foo"), "CancelWatchConfig did not prevent second change from being seen.")
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkGetBool(b *testing.B) {
|
||||
|
|
Loading…
Reference in a new issue