fix(proxy): align config watcher with RFC
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
ce3b7a50cd
commit
f2f7dfed75
4 changed files with 26 additions and 60 deletions
74
core_impl.go
74
core_impl.go
|
|
@ -11,13 +11,10 @@ import (
|
|||
"math"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
)
|
||||
|
||||
// Result is the success/error carrier used by constructors and loaders.
|
||||
|
|
@ -367,6 +364,9 @@ 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()
|
||||
}
|
||||
|
|
@ -379,65 +379,42 @@ func (w *ConfigWatcher) Start() {
|
|||
return
|
||||
}
|
||||
w.mu.Lock()
|
||||
if w.watcher != nil {
|
||||
if w.started {
|
||||
w.mu.Unlock()
|
||||
return
|
||||
}
|
||||
fsWatcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
w.mu.Unlock()
|
||||
return
|
||||
}
|
||||
w.watcher = fsWatcher
|
||||
w.started = true
|
||||
w.mu.Unlock()
|
||||
|
||||
watchPath := filepath.Clean(w.path)
|
||||
watchDir := filepath.Dir(watchPath)
|
||||
if watchDir == "" {
|
||||
watchDir = "."
|
||||
}
|
||||
if err := fsWatcher.Add(watchDir); err != nil {
|
||||
_ = fsWatcher.Close()
|
||||
w.mu.Lock()
|
||||
if w.watcher == fsWatcher {
|
||||
w.watcher = nil
|
||||
}
|
||||
w.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
_ = fsWatcher.Close()
|
||||
w.mu.Lock()
|
||||
if w.watcher == fsWatcher {
|
||||
w.watcher = nil
|
||||
}
|
||||
w.mu.Unlock()
|
||||
}()
|
||||
ticker := time.NewTicker(time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-fsWatcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if filepath.Clean(event.Name) != watchPath {
|
||||
case <-ticker.C:
|
||||
data, err := os.ReadFile(w.path)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if event.Op&(fsnotify.Write|fsnotify.Create|fsnotify.Rename|fsnotify.Remove|fsnotify.Chmod) == 0 {
|
||||
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()
|
||||
w.mu.Unlock()
|
||||
}
|
||||
config, result := LoadConfig(w.path)
|
||||
if result.OK && config != nil {
|
||||
if info, err := os.Stat(w.path); err == nil {
|
||||
w.lastMod = info.ModTime()
|
||||
}
|
||||
w.onChange(config)
|
||||
}
|
||||
case _, ok := <-fsWatcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
case <-w.done:
|
||||
return
|
||||
}
|
||||
|
|
@ -451,10 +428,7 @@ func (w *ConfigWatcher) Stop() {
|
|||
return
|
||||
}
|
||||
w.mu.Lock()
|
||||
if w.watcher != nil {
|
||||
_ = w.watcher.Close()
|
||||
w.watcher = nil
|
||||
}
|
||||
w.started = false
|
||||
w.mu.Unlock()
|
||||
select {
|
||||
case <-w.done:
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -1,7 +1,3 @@
|
|||
module dappco.re/go/proxy
|
||||
|
||||
go 1.26.0
|
||||
|
||||
require github.com/fsnotify/fsnotify v1.7.0
|
||||
|
||||
require golang.org/x/sys v0.4.0 // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -1,4 +0,0 @@
|
|||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
4
proxy.go
4
proxy.go
|
|
@ -8,7 +8,6 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"net/http"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
|
@ -120,9 +119,10 @@ type ConfigWatcher struct {
|
|||
path string
|
||||
onChange func(*Config)
|
||||
lastMod time.Time
|
||||
lastSum [32]byte
|
||||
done chan struct{}
|
||||
mu sync.Mutex
|
||||
watcher *fsnotify.Watcher
|
||||
started bool
|
||||
}
|
||||
|
||||
// RateLimiter throttles new connections per source IP.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue