From a04a36bf90b2ac82c4a1411a8f03f0e39252a4e2 Mon Sep 17 00:00:00 2001 From: Gregory Eremin Date: Sat, 29 Aug 2015 16:25:40 +0300 Subject: [PATCH] Handle file system events to reload config --- secondly.go | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/secondly.go b/secondly.go index b0d70ee..0e14cc9 100644 --- a/secondly.go +++ b/secondly.go @@ -6,8 +6,12 @@ import ( "log" "os" "os/signal" + "path/filepath" "reflect" + "strings" "syscall" + + "github.com/howeyc/fsnotify" ) var ( @@ -17,8 +21,8 @@ var ( initialized bool ) -// SetFlags sets up Confection configuration flags. -func SetFlags() { +// SetupFlags sets up Confection configuration flags. +func SetupFlags() { flag.StringVar(&configFile, "config", "config.json", "Path to config file") } @@ -46,6 +50,41 @@ func HandleSIGHUP() { }() } +// HandleFSEvents listens to file system events and reloads configuration when +// config file is modified. +func HandleFSEvents() { + watcher, err := fsnotify.NewWatcher() + if err != nil { + panic(err) + } + if err := watcher.WatchFlags(filepath.Dir(configFile), fsnotify.FSN_MODIFY); err != nil { + panic(err) + } + + fname := configFile + if ss := strings.Split(configFile, "/"); len(ss) > 1 { + fname = ss[len(ss)-1] + } + + go func() { + for { + select { + case e := <-watcher.Event: + if e.Name != fname { + continue + } + if !e.IsModify() { + continue + } + log.Println("Config file was modified, reloading") + readConfig() + case err := <-watcher.Error: + log.Println("fsnotify error:", err) + } + } + }() +} + // OnChange adds a callback function that is triggered every time a value of // a field changes. func OnChange(field string, fun func(oldVal, newVal interface{})) { @@ -103,6 +142,10 @@ func triggerCallbacks(oldConf, newConf interface{}) { return } + if len(callbacks) == 0 { + return + } + for fname, d := range diff(oldConf, newConf) { if cbs, ok := callbacks[fname]; ok { for _, cb := range cbs {