Go - Live reload of configurations

发布时间 2023-09-27 15:22:50作者: ZhangZhihuiAAA

main.go:

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "time"

    "github.com/fsnotify/fsnotify"
)

type config struct {
    Name string `json:"name"`
}

func readConfig() config {
    raw, _ := os.ReadFile("config.json")
    var c config
    json.Unmarshal(raw, &c)
    return c
}

func main() {
    currentConfig := readConfig()

    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    watcher.Add("config.json")

    for {
        time.Sleep(time.Second)
        select {
        case event := <-watcher.Events:
            fmt.Printf("Event happened: %v\n", event)
            if event.Has(fsnotify.Write) {
                currentConfig = readConfig()
                fmt.Println("configuration is updated")
            }
        default:
            fmt.Printf("%+v\n", currentConfig)
        }
    }
}

config.json:

{
    "name": "initial"
}

 

zzh@ZZHPC:/zdata/MyPrograms/Go/ccc$ go run main.go
{Name:initial}
{Name:initial}
{Name:initial}
{Name:initial}
{Name:initial}
Event happened: WRITE         "config.json"
configuration is updated
Event happened: WRITE         "config.json"
configuration is updated
{Name:updated}
{Name:updated}
{Name:updated}
{Name:updated}
{Name:updated}
^Csignal: interrupt

There were two WRITE events, which can be explained by below documentation of fsnotify (https://pkg.go.dev/github.com/fsnotify/fsnotify):

    //   fsnotify.Write     A file or named pipe was written to. A Truncate will
    //                      also trigger a Write. A single "write action"
    //                      initiated by the user may show up as one or multiple
    //                      writes, depending on when the system syncs things to
    //                      disk. For example when compiling a large Go program
    //                      you may get hundreds of Write events, so you
    //                      probably want to wait until you've stopped receiving
    //                      them (see the dedup example in cmd/fsnotify).