Как использовать 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,

Другие вопросы по тегам