// Gives control of chan to caller func (mr *ModRunner) runOnChan(modchan chan *moddwatch.Mod, readyCallback func()) error { dworld, err := NewDaemonWorld(mr.Config, mr.Log) if err != nil { return err } defer dworld.Shutdown(os.Kill) c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, os.Kill) defer signal.Reset(os.Interrupt, os.Kill) go func() { dworld.Shutdown(<-c) os.Exit(0) }() watchpaths := mr.Config.WatchPatterns() if mr.ConfReload { watchpaths = append(watchpaths, filepath.Dir(mr.ConfPath)) } // FIXME: This takes a long time. We could start it in parallel with the // first process run in a goroutine watcher, err := moddwatch.Watch(watchpaths, lullTime, modchan) if err != nil { return fmt.Errorf("Error watching: %s", err) } defer watcher.Stop() mr.trigger(nil, dworld) go readyCallback() for mod := range modchan { if mod == nil { break } if mr.ConfReload && mod.Has(mr.ConfPath) { mr.Log.Notice("Reloading config %s", mr.ConfPath) err := mr.ReadConfig() if err != nil { mr.Log.Warn("%s", err) continue } else { return nil } } mr.Log.SayAs("debug", "Delta: \n%s", mod.String()) mr.trigger(mod, dworld) } return nil }
// WatchPaths watches a set of paths, and broadcasts changes through reloader. func WatchPaths(paths, excludePatterns []string, reloader livereload.Reloader, log termlog.Logger) error { ch := make(chan []string, 1) for _, path := range paths { modchan := make(chan *moddwatch.Mod, 1) _, err := moddwatch.Watch([]string{path}, batchTime, modchan) if err != nil { return err } go func() { for mod := range modchan { filteredMod, err := mod.Filter([]string{"**/*"}, excludePatterns) if err != nil { log.Shout("Error filtering watches: %s", err) } if !filteredMod.Empty() { ch <- filteredMod.All() } } }() } go reloader.Watch(ch) return nil }
// Watch watches an endpoint for changes, if it supports them. func (r Route) Watch(ch chan []string, excludePatterns []string, log termlog.Logger) error { switch r.Endpoint.(type) { case *filesystemEndpoint: ep := *r.Endpoint.(*filesystemEndpoint) modchan := make(chan *moddwatch.Mod, 1) _, err := moddwatch.Watch([]string{ep.Root + "/..."}, batchTime, modchan) if err != nil { return err } go func() { for mod := range modchan { filteredMod, err := mod.Filter([]string{"**/*"}, excludePatterns) if err != nil { log.Shout("Error filtering watches: %s", err) } if !filteredMod.Empty() { ch <- filteredMod.All() } } }() } return nil }