优化结构
This commit is contained in:
@@ -33,43 +33,77 @@ func (d *Data) watchConfig() func() {
|
||||
return func() {}
|
||||
}
|
||||
done := make(chan struct{})
|
||||
finished := make(chan struct{})
|
||||
var once sync.Once
|
||||
go func() {
|
||||
defer close(finished)
|
||||
var timer *time.Timer
|
||||
var timerC <-chan time.Time
|
||||
events := watcher.Events
|
||||
watchErrors := watcher.Errors
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok || filepath.Clean(event.Name) != absolute || event.Op&(fsnotify.Write|fsnotify.Create|fsnotify.Rename) == 0 {
|
||||
case event, ok := <-events:
|
||||
if !ok {
|
||||
events = nil
|
||||
continue
|
||||
}
|
||||
if filepath.Clean(event.Name) != absolute || event.Op&(fsnotify.Write|fsnotify.Create|fsnotify.Rename) == 0 {
|
||||
continue
|
||||
}
|
||||
if timer != nil {
|
||||
timer.Stop()
|
||||
if !timer.Stop() {
|
||||
select {
|
||||
case <-timer.C:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
timer = time.AfterFunc(100*time.Millisecond, func() {
|
||||
next, loadErr := readBootstrap(absolute)
|
||||
if loadErr != nil {
|
||||
logger.Error("reload changed config", "mod", "system", "error", loadErr)
|
||||
return
|
||||
}
|
||||
if next.Data == nil || next.Admin == nil {
|
||||
logger.Error("reload changed config: data and admin configuration are required", "mod", "system")
|
||||
return
|
||||
}
|
||||
if current := d.runtime.Admin(); current != nil {
|
||||
next.Admin.Storage = current.Storage
|
||||
next.Admin.Email = current.Email
|
||||
}
|
||||
next.Admin.ConfigPath = absolute
|
||||
d.runtime.Replace(next.Data, next.Admin)
|
||||
logger.Info("config file changed", "mod", "system", "path", absolute)
|
||||
})
|
||||
case watchErr, ok := <-watcher.Errors:
|
||||
if ok {
|
||||
logger.Error("config watcher error", "mod", "system", "error", watchErr)
|
||||
if timer == nil {
|
||||
timer = time.NewTimer(100 * time.Millisecond)
|
||||
} else {
|
||||
timer.Reset(100 * time.Millisecond)
|
||||
}
|
||||
timerC = timer.C
|
||||
case <-timerC:
|
||||
// The debounce callback runs on this goroutine so shutdown can
|
||||
// wait for it to finish without racing runtime replacement.
|
||||
timerC = nil
|
||||
select {
|
||||
case <-done:
|
||||
continue
|
||||
default:
|
||||
}
|
||||
next, loadErr := readBootstrap(absolute)
|
||||
if loadErr != nil {
|
||||
logger.Error("reload changed config", "mod", "system", "error", loadErr)
|
||||
continue
|
||||
}
|
||||
if next.Data == nil || next.Admin == nil {
|
||||
logger.Error("reload changed config: data and admin configuration are required", "mod", "system")
|
||||
continue
|
||||
}
|
||||
if current := d.runtime.Admin(); current != nil {
|
||||
next.Admin.Storage = current.Storage
|
||||
next.Admin.Email = current.Email
|
||||
}
|
||||
next.Admin.ConfigPath = absolute
|
||||
d.runtime.Replace(next.Data, next.Admin)
|
||||
logger.Info("config file changed", "mod", "system", "path", absolute)
|
||||
case watchErr, ok := <-watchErrors:
|
||||
if !ok {
|
||||
watchErrors = nil
|
||||
continue
|
||||
}
|
||||
logger.Error("config watcher error", "mod", "system", "error", watchErr)
|
||||
case <-done:
|
||||
if timer != nil {
|
||||
timer.Stop()
|
||||
if !timer.Stop() {
|
||||
select {
|
||||
case <-timer.C:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -79,6 +113,7 @@ func (d *Data) watchConfig() func() {
|
||||
once.Do(func() {
|
||||
close(done)
|
||||
_ = watcher.Close()
|
||||
<-finished
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user