fix(proxy): use mtime-based config watching
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
cbde021d0c
commit
356eb9cec1
3 changed files with 56 additions and 27 deletions
|
|
@ -48,6 +48,10 @@ func TestConfigWatcher_Start_Good(t *testing.T) {
|
|||
if err := os.WriteFile(path, updated, 0o644); err != nil {
|
||||
t.Fatalf("write updated config file: %v", err)
|
||||
}
|
||||
now := time.Now()
|
||||
if err := os.Chtimes(path, now, now.Add(2*time.Second)); err != nil {
|
||||
t.Fatalf("touch updated config file: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case cfg := <-updates:
|
||||
|
|
@ -61,3 +65,42 @@ func TestConfigWatcher_Start_Good(t *testing.T) {
|
|||
t.Fatal("expected watcher to reload updated config")
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfigWatcher_Start_Ugly(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "config.json")
|
||||
initial := []byte(`{"mode":"nicehash","workers":"false","bind":[{"host":"127.0.0.1","port":3333}],"pools":[{"url":"pool.example:3333","enabled":true}]}`)
|
||||
if err := os.WriteFile(path, initial, 0o644); err != nil {
|
||||
t.Fatalf("write initial config file: %v", err)
|
||||
}
|
||||
|
||||
updates := make(chan *Config, 1)
|
||||
watcher := NewConfigWatcher(path, func(cfg *Config) {
|
||||
select {
|
||||
case updates <- cfg:
|
||||
default:
|
||||
}
|
||||
})
|
||||
if watcher == nil {
|
||||
t.Fatal("expected watcher")
|
||||
}
|
||||
watcher.Start()
|
||||
defer watcher.Stop()
|
||||
|
||||
now := time.Now()
|
||||
if err := os.Chtimes(path, now, now.Add(2*time.Second)); err != nil {
|
||||
t.Fatalf("touch config file: %v", err)
|
||||
}
|
||||
|
||||
select {
|
||||
case cfg := <-updates:
|
||||
if cfg == nil {
|
||||
t.Fatal("expected config update")
|
||||
}
|
||||
if got := cfg.Mode; got != "nicehash" {
|
||||
t.Fatalf("expected unchanged mode, got %q", got)
|
||||
}
|
||||
case <-time.After(5 * time.Second):
|
||||
t.Fatal("expected watcher to reload touched config")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
33
core_impl.go
33
core_impl.go
|
|
@ -364,9 +364,6 @@ func NewConfigWatcher(configPath string, onChange func(*Config)) *ConfigWatcher
|
|||
onChange: onChange,
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
if data, err := os.ReadFile(configPath); err == nil {
|
||||
watcher.lastSum = sha256.Sum256(data)
|
||||
}
|
||||
if info, err := os.Stat(configPath); err == nil {
|
||||
watcher.lastMod = info.ModTime()
|
||||
}
|
||||
|
|
@ -392,28 +389,20 @@ func (w *ConfigWatcher) Start() {
|
|||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
data, err := os.ReadFile(w.path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
sum := sha256.Sum256(data)
|
||||
w.mu.Lock()
|
||||
changed := sum != w.lastSum
|
||||
if changed {
|
||||
w.lastSum = sum
|
||||
}
|
||||
w.mu.Unlock()
|
||||
if !changed {
|
||||
continue
|
||||
}
|
||||
if info, err := os.Stat(w.path); err == nil {
|
||||
w.mu.Lock()
|
||||
w.lastMod = info.ModTime()
|
||||
changed := info.ModTime() != w.lastMod
|
||||
if changed {
|
||||
w.lastMod = info.ModTime()
|
||||
}
|
||||
w.mu.Unlock()
|
||||
}
|
||||
config, result := LoadConfig(w.path)
|
||||
if result.OK && config != nil {
|
||||
w.onChange(config)
|
||||
if !changed {
|
||||
continue
|
||||
}
|
||||
config, result := LoadConfig(w.path)
|
||||
if result.OK && config != nil {
|
||||
w.onChange(config)
|
||||
}
|
||||
}
|
||||
case <-w.done:
|
||||
return
|
||||
|
|
|
|||
7
proxy.go
7
proxy.go
|
|
@ -110,16 +110,13 @@ type CloseEvent struct {
|
|||
Miner *Miner
|
||||
}
|
||||
|
||||
// ConfigWatcher polls a config file for changes.
|
||||
// ConfigWatcher polls a config file every second and reloads on modification.
|
||||
//
|
||||
// watcher := proxy.NewConfigWatcher("config.json", func(cfg *proxy.Config) {
|
||||
// p.Reload(cfg)
|
||||
// })
|
||||
// watcher := proxy.NewConfigWatcher("config.json", func(cfg *proxy.Config) { p.Reload(cfg) })
|
||||
type ConfigWatcher struct {
|
||||
path string
|
||||
onChange func(*Config)
|
||||
lastMod time.Time
|
||||
lastSum [32]byte
|
||||
done chan struct{}
|
||||
mu sync.Mutex
|
||||
started bool
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue