From b1af2e00813c2a2ebdbe40c3ff4e70e49aa6d1ac Mon Sep 17 00:00:00 2001 From: Virgil Date: Sat, 4 Apr 2026 15:58:27 +0000 Subject: [PATCH] fix(proxy): honour disabled config watcher Co-Authored-By: Virgil --- config_runtime.go | 7 ++++++- config_runtime_test.go | 32 +++++++++++++++++++++++++++++++- proxy.go | 1 + proxy_runtime.go | 2 +- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/config_runtime.go b/config_runtime.go index fbf81a1..2439c7c 100644 --- a/config_runtime.go +++ b/config_runtime.go @@ -63,9 +63,14 @@ func (c *Config) Validate() error { // // w := proxy.NewConfigWatcher("config.json", func(cfg *proxy.Config) { p.Reload(cfg) }) func NewConfigWatcher(path string, onChange func(*Config)) *ConfigWatcher { + return newConfigWatcher(path, onChange, true) +} + +func newConfigWatcher(path string, onChange func(*Config), enabled bool) *ConfigWatcher { return &ConfigWatcher{ path: path, onChange: onChange, + enabled: enabled, done: make(chan struct{}), } } @@ -74,7 +79,7 @@ func NewConfigWatcher(path string, onChange func(*Config)) *ConfigWatcher { // // w.Start() func (w *ConfigWatcher) Start() { - if w == nil { + if w == nil || !w.enabled { return } diff --git a/config_runtime_test.go b/config_runtime_test.go index 83fd920..06732aa 100644 --- a/config_runtime_test.go +++ b/config_runtime_test.go @@ -1,6 +1,10 @@ package proxy -import "testing" +import ( + "os" + "testing" + "time" +) func TestConfig_Validate_Good(t *testing.T) { cfg := &Config{ @@ -36,3 +40,29 @@ func TestConfig_Validate_Ugly(t *testing.T) { t.Fatal("expected empty enabled pool URL to fail validation") } } + +func TestConfigWatcher_Start_Bad(t *testing.T) { + path := t.TempDir() + "/config.json" + errorValue := os.WriteFile(path, []byte(`{"bind":[{"host":"127.0.0.1","port":3333}],"pools":[{"url":"pool-a:3333","enabled":true}]}`), 0o644) + if errorValue != nil { + t.Fatal(errorValue) + } + + triggered := make(chan struct{}, 1) + watcher := newConfigWatcher(path, func(cfg *Config) { + triggered <- struct{}{} + }, false) + watcher.Start() + defer watcher.Stop() + + errorValue = os.WriteFile(path, []byte(`{"bind":[{"host":"127.0.0.1","port":3333}],"pools":[{"url":"pool-b:3333","enabled":true}]}`), 0o644) + if errorValue != nil { + t.Fatal(errorValue) + } + + select { + case <-triggered: + t.Fatal("expected disabled watcher to stay quiet") + case <-time.After(1200 * time.Millisecond): + } +} diff --git a/proxy.go b/proxy.go index b4c7d47..3af9147 100644 --- a/proxy.go +++ b/proxy.go @@ -98,6 +98,7 @@ type CloseEvent struct { type ConfigWatcher struct { path string onChange func(*Config) + enabled bool lastModifiedAt time.Time done chan struct{} } diff --git a/proxy_runtime.go b/proxy_runtime.go index 578d13f..5ef9b5d 100644 --- a/proxy_runtime.go +++ b/proxy_runtime.go @@ -91,7 +91,7 @@ func New(config *Config) (*Proxy, error) { }) } if config.Watch && config.sourcePath != "" { - proxyInstance.watcher = NewConfigWatcher(config.sourcePath, proxyInstance.Reload) + proxyInstance.watcher = newConfigWatcher(config.sourcePath, proxyInstance.Reload, config.Watch) proxyInstance.watcher.Start() }