diff --git a/lib/config/health.go b/lib/config/health.go index 5e76b0a0..31fe30df 100644 --- a/lib/config/health.go +++ b/lib/config/health.go @@ -15,5 +15,5 @@ package config type HealthInfo struct { - ConfigVersion uint32 `json:"config_version"` + ConfigChecksum uint32 `json:"config_checksum"` } diff --git a/pkg/manager/config/config.go b/pkg/manager/config/config.go index ca3318aa..bb5e4c01 100644 --- a/pkg/manager/config/config.go +++ b/pkg/manager/config/config.go @@ -15,6 +15,8 @@ package config import ( + "bytes" + "hash/crc32" "os" "time" @@ -74,8 +76,9 @@ func (e *ConfigManager) SetTOMLConfig(data []byte) error { return err } - e.sts.current = base - e.sts.version++ + if err := e.setCurrentConfig(base); err != nil { + return err + } for _, list := range e.sts.listeners { list <- base.Clone() @@ -84,6 +87,16 @@ func (e *ConfigManager) SetTOMLConfig(data []byte) error { return nil } +func (e *ConfigManager) setCurrentConfig(cfg *config.Config) error { + e.sts.current = cfg + var buf bytes.Buffer + if err := toml.NewEncoder(&buf).Encode(cfg); err != nil { + return err + } + e.sts.checksum = crc32.ChecksumIEEE(buf.Bytes()) + return nil +} + func (e *ConfigManager) GetConfig() *config.Config { e.sts.Lock() v := e.sts.current @@ -91,11 +104,11 @@ func (e *ConfigManager) GetConfig() *config.Config { return v } -func (e *ConfigManager) GetConfigVersion() uint32 { +func (e *ConfigManager) GetConfigChecksum() uint32 { e.sts.Lock() - v := e.sts.version + c := e.sts.checksum e.sts.Unlock() - return v + return c } func (e *ConfigManager) WatchConfig() <-chan *config.Config { diff --git a/pkg/manager/config/config_test.go b/pkg/manager/config/config_test.go index 421110ab..eb6395cf 100644 --- a/pkg/manager/config/config_test.go +++ b/pkg/manager/config/config_test.go @@ -163,3 +163,18 @@ func TestConfigRemove(t *testing.T) { require.NoError(t, os.WriteFile(tmpcfg, []byte(`proxy.addr = "vv"`), 0644)) require.Eventually(t, func() bool { return cfgmgr.GetConfig().Proxy.Addr == "vv" }, time.Second, 100*time.Millisecond) } + +func TestChecksum(t *testing.T) { + cfgmgr, _ := testConfigManager(t, "") + c1 := cfgmgr.GetConfigChecksum() + require.NoError(t, cfgmgr.SetTOMLConfig([]byte(`proxy.addr = "gg"`))) + c2 := cfgmgr.GetConfigChecksum() + require.NoError(t, cfgmgr.SetTOMLConfig([]byte(`proxy.addr = "vv"`))) + c3 := cfgmgr.GetConfigChecksum() + require.NoError(t, cfgmgr.SetTOMLConfig([]byte(`proxy.addr="gg"`))) + c4 := cfgmgr.GetConfigChecksum() + require.Equal(t, c2, c4) + require.NotEqual(t, c1, c2) + require.NotEqual(t, c1, c3) + require.NotEqual(t, c2, c3) +} diff --git a/pkg/manager/config/manager.go b/pkg/manager/config/manager.go index 79804948..27d4bab3 100644 --- a/pkg/manager/config/manager.go +++ b/pkg/manager/config/manager.go @@ -56,7 +56,7 @@ type ConfigManager struct { sync.Mutex listeners []chan<- *config.Config current *config.Config - version uint32 + checksum uint32 } } diff --git a/pkg/server/api/debug.go b/pkg/server/api/debug.go index 463e57cd..46eefb4e 100644 --- a/pkg/server/api/debug.go +++ b/pkg/server/api/debug.go @@ -24,7 +24,7 @@ import ( func (h *HTTPServer) DebugHealth(c *gin.Context) { c.JSON(http.StatusOK, config.HealthInfo{ - ConfigVersion: h.mgr.cfg.GetConfigVersion(), + ConfigChecksum: h.mgr.cfg.GetConfigChecksum(), }) }