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 {