Как использовать golang viper Watchconfig и onConfigChange
Я пытаюсь прочитать конфигурацию своего приложения, используя golang viper, и хотел бы всегда читать последнюю версию конфигурации. Пожалуйста, найдите мой код ниже
config.go
package config
import (
"github.com/spf13/viper"
"log"
"github.com/fsnotify/fsnotify"
"time"
)
type Reader interface {
GetAllKeys() []string
Get(key string) interface{}
GetBool(key string) bool
GetString(key string) string
}
type viperConfigReader struct {
viper *viper.Viper
}
var TestConfReader *viperConfigReader
func (v viperConfigReader) GetAllKeys() []string{
return v.viper.AllKeys()
}
func (v viperConfigReader) Get(key string) interface{} {
return v.viper.Get(key)
}
func (v viperConfigReader) GetBool(key string) bool {
return v.viper.GetBool(key)
}
func (v viperConfigReader) GetString(key string) string {
return v.viper.GetString(key)
}
func init() {
v:= viper.New()
v.SetConfigName("test")
v.AddConfigPath("/tmp/")
err := v.ReadInConfig()
if err != nil {
log.Panic("Not able to read configuration", err.Error())
}
TestConfReader = &viperConfigReader{
viper: v,
}
go func() {
for {
time.Sleep(time.Second * 5)
v.WatchConfig()
v.OnConfigChange(func(e fsnotify.Event) {
log.Println("config file changed", e.Name)
})
}
}()
}
main.go
package main
import (
"github.com/xxxx/xxxx/config"
"log"
"time"
)
func main() {
conf := config.TestConfReader
log.Println(conf.GetAllKeys())
log.Println(conf.GetString("test1"))
time.Sleep(20 * time.Second)
log.Println(conf.GetString("test1"))
}
Когда основная программа запущена, я попытался обновить конфигурацию и ожидал увидеть сообщение журнала OnConfigChange, но оно так и не появилось.
Как я могу исправить эту программу?
Может ли кто-нибудь привести пример использования методов viper watchconfig & onconfigchange для чтения последней конфигурации
1 ответ
Комментарий ymonad находится на правильном пути, в зависимости от вашей ОС у вас могут возникнуть проблемы с viper / fsnotify.
Например, я запустил ваш пример кода в Mac OS X (Sierra) и заметил тот же симптом, который вы описали: когда файл конфигурации находится в /tmp
гадюка WatchConfig
звонок не вызывал гадюку OnConfigChange
функция должна быть вызвана.
Тем не менее, когда я меняю AddConfigPath
чтобы использовать текущий рабочий каталог или мой домашний каталог, то я вижу, логирование с вашего OnConfigChange
функция. Например, попробуйте:
v.AddConfigPath("./")
Я бы порекомендовал поэкспериментировать с различными каталогами, чтобы увидеть, является ли это какой-то ошибкой или ограничением viper / fsnotify. По некоторым причинам, он не обнаруживает изменений от /tmp
каталог в Mac OS X, по крайней мере, это не для моей настройки. Я не мог найти упоминания о проблемах с /tmp
на OS X, но fsnotify CONTRIBUTING.md упоминает ограничения для "общих" каталогов под Vagrant, поэтому, возможно, существуют некоторые конфигурации файловой системы, которые не вызывают уведомления:
Примечание: события файловой системы fsnotify не будут запускаться в общих папках. Тесты обойдут это ограничение, используя каталог / tmp.
Кроме того, вам не нужно продолжать звонить WatchConfig
а также OnConfigChange
через вашу программу Вы можете полностью устранить goroutine и просто переместить соответствующие строки в init
,