diff --git a/config/config.go b/config/config.go index e986960..4ff86bc 100644 --- a/config/config.go +++ b/config/config.go @@ -38,7 +38,8 @@ type ConfigV2 struct { } type ConfigService struct { - Config ConfigV2 + Config *ConfigV2 + Changed chan bool ConfigFilename string } @@ -57,7 +58,7 @@ func (c *ConfigService) LoadOrInit() error { if os.IsNotExist(err) { daulog.SendLog("NOTE: No config file, writing out sample configuration", daulog.LogTypeInfo) daulog.SendLog("You need to set the configuration via the web interface", daulog.LogTypeInfo) - c.Config = *DefaultConfig() + c.Config = DefaultConfig() return c.Save() } else { return c.Load() @@ -158,6 +159,7 @@ func (c *ConfigService) Save() error { if err != nil { return fmt.Errorf("cannot save config %s: %s", c.ConfigFilename, err.Error()) } + return nil } diff --git a/dau.go b/dau.go index 16264bd..ccef88c 100644 --- a/dau.go +++ b/dau.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/json" "flag" "fmt" @@ -39,8 +40,10 @@ func main() { parseOptions() - // grab the config + // grab the config, register to notice changes config := config.DefaultConfigService() + configChanged := make(chan bool) + config.Changed = configChanged config.LoadOrInit() // create the uploader @@ -48,34 +51,50 @@ func main() { // log.Print("Opening web browser") // open.Start("http://localhost:9090") - web := web.WebService{Config: *config} + web := web.WebService{Config: config} web.StartWebServer() go func() { checkUpdates() }() - // create the watchers + // create the watchers, restart them if config changes + // blocks forever + startWatchers(config, &up, configChanged) - log.Printf("Conf: %#v", config.Config) - - for _, c := range config.Config.Watchers { - log.Printf("Creating watcher for %v", c) - watcher := watch{uploader: up, lastCheck: time.Now(), newLastCheck: time.Now(), config: c} - go watcher.Watch(config.Config.WatchInterval) - } - - select {} } -func (w *watch) Watch(interval int) { +func startWatchers(config *config.ConfigService, up *upload.Uploader, configChange chan bool) { for { - newFiles := w.ProcessNewFiles() - for _, f := range newFiles { - w.uploader.AddFile(f, w.config) + log.Printf("Creating watchers") + ctx, cancel := context.WithCancel(context.Background()) + for _, c := range config.Config.Watchers { + log.Printf("Creating watcher for %s interval %d", c.Path, config.Config.WatchInterval) + watcher := watch{uploader: *up, lastCheck: time.Now(), newLastCheck: time.Now(), config: c} + go watcher.Watch(config.Config.WatchInterval, ctx) + } + // wait for single that the config changed + <-configChange + cancel() + log.Printf("starting new watchers due to config change") + } + +} + +func (w *watch) Watch(interval int, ctx context.Context) { + for { + select { + case <-ctx.Done(): + log.Printf("Killing old watcher") + return + default: + newFiles := w.ProcessNewFiles() + for _, f := range newFiles { + w.uploader.AddFile(f, w.config) + } + // upload them + w.uploader.Upload() + daulog.SendLog(fmt.Sprintf("sleeping for %ds before next check of %s", interval, w.config.Path), daulog.LogTypeDebug) + time.Sleep(time.Duration(interval) * time.Second) } - // upload them - w.uploader.Upload() - daulog.SendLog(fmt.Sprintf("sleeping for %ds before next check of %s", interval, w.config.Path), daulog.LogTypeDebug) - time.Sleep(time.Duration(interval) * time.Second) } } @@ -119,7 +138,6 @@ func (w *watch) checkPath() bool { // If the file is eligible, not excluded and new enough to care we add it // to the passed in array of files func (w *watch) checkFile(path string, found *[]string, exclusions []string) error { - log.Printf("Considering %s", path) extension := strings.ToLower(filepath.Ext(path)) diff --git a/web/server.go b/web/server.go index 501ff01..f0f42c2 100644 --- a/web/server.go +++ b/web/server.go @@ -18,7 +18,7 @@ import ( ) type WebService struct { - Config config.ConfigService + Config *config.ConfigService } //go:embed data @@ -129,7 +129,7 @@ func (ws *WebService) handleConfig(w http.ResponseWriter, r *http.Request) { w.Write(j) return } - ws.Config.Config = newConfig + ws.Config.Config = &newConfig err = ws.Config.Save() if err != nil { w.WriteHeader(400) @@ -138,6 +138,11 @@ func (ws *WebService) handleConfig(w http.ResponseWriter, r *http.Request) { return } + // config has changed, so tell the world + if ws.Config.Changed != nil { + ws.Config.Changed <- true + } + } b, _ := json.Marshal(ws.Config.Config)