GO的Viper的问题,哪位大佬能帮我解答一下呀?

2023-06-16 304 0

目前使用的是直接读取app.ini配置文件,然后再映射,简单粗暴,但是问题就是不能实时动态修改,所以上网寻找解决方案,看到大家都推荐Viper,所以尝试了一下,但是发现了个问题,虽然能够动态获取到改变的值,但是这个值并没有在程序中生效哇,具体问题解释如下:

app.ini

[kafka]
TimeExec = 20

main.go:

func main() {
    viper.SetConfigName("app")
    viper.SetConfigType("ini")
    viper.AddConfigPath(".")
    err := viper.ReadInConfig()
    if err != nil {
        log.Fatal("read config failed: %v", err)
    }
    viper.WatchConfig()
    viper.OnConfigChange(func(e fsnotify.Event) {
        fmt.Println("Config file changed:", e.Name)
    })
    // 执行定时任务
    ticker := time.NewTicker(viper.GetDuration("kafka.TimeExec"))
    defer ticker.Stop()
    for {
        select {
        case <-ticker.C:
            fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
            fmt.Println("间隔:" + viper.GetDuration("kafka.TimeExec"))
        }
    }
}

启动程序,项目20s执行一次,并且打印出间隔 20s。

这时候当我更改了配置文件,改为10s,确实会监控到并且也会执行OnConfigChange打印信息、也会打印出:间隔:10s,但是定时还是20s执行一次呀,这是为什么呢?

time.NewTicker 方法执行的时候创建了 ticker ,创建的时候指定了间隔时间,那么这个 ticker 就会以这个间隔时间执行。

最简单的修改思路是,当文件变更时,调用 Reset 方法重置 ticker 的间隔时间。

func main() {
    viper.SetConfigName("app")
    viper.SetConfigType("ini")
    viper.AddConfigPath(".")
    err := viper.ReadInConfig()
    if err != nil {
        log.Fatal("read config failed: %v", err)
    }
    viper.WatchConfig()
    // 执行定时任务
    ticker := time.NewTicker(viper.GetDuration("kafka.TimeExec") * time.Second)
    defer ticker.Stop()
    viper.OnConfigChange(func(e fsnotify.Event) {
        fmt.Println("Config file changed:", e.Name)
        ticker.Reset(viper.GetDuration("kafka.TimeExec") * time.Second)
    })
    for {
        select {
        case <-ticker.C:
            fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
            fmt.Println("间隔:", viper.GetDuration("kafka.TimeExec")*time.Second)
        }
    }
}

image.png

回答

相关文章

nuxt2部署静态化和ssr的时候访问首页先报404再出现首页为什么?
`clip-path` 如何绘制圆角平行四边形呢?
多线程wait方法报错?
VUE 绑定的方法如何直接使用外部函数?
vue2固定定位该怎么做?
谁有redis实现信号量的代码,希望借鉴一下?