// Init ensures the internal state of the watcher is properly initialized func (w *Watcher) Init() (err error) { if w.inited { return nil } w.fs, err = fsnotify.NewWatcher() if err != nil { return } stat, err := os.Stat(w.Dir) if err != nil { return } if !stat.IsDir() { err = fmt.Errorf("%s is not a directory", w.Dir) return } w.changes = make(chan string, 100) w.done = make(chan bool, 1) w.pending = make(map[string]bool) w.inited = true return }
func (h *handler) watcher(f string) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event := <-watcher.Events: log.Println("event:", event) if event.Op&fsnotify.Write == fsnotify.Write { log.Println("modified file:", event.Name) h.c <- true } case err := <-watcher.Errors: log.Println("error:", err) } } }() err = watcher.Add(f) if err != nil { log.Fatal(err) } <-done }
// WatchDir watches a directory and execute callback on any changes. func (b *Base) WatchDir(path string, callback func() error) error { watcher, err := fsnotify.NewWatcher() if err != nil { return err } defer watcher.Close() err = watcher.Add(path) if err != nil { return err } for { select { case event := <-watcher.Events: if (event.Op&fsnotify.Create == fsnotify.Create) || (event.Op&fsnotify.Remove == fsnotify.Remove) || (event.Op&fsnotify.Write == fsnotify.Write) || (event.Op&fsnotify.Rename == fsnotify.Rename) { logrus.WithFields(logrus.Fields{ "Path": path, "Event": event.String(), }).Info("Changes happened, executing callback") callback() } case err := <-watcher.Errors: if err != nil { logrus.WithFields(logrus.Fields{ "Error": err.Error(), "Path": path, }).Error("Error while watching path") } } } return nil }
// watch file change func RunWatcher(path string) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event := <-watcher.Events: if event.Op&fsnotify.Write == fsnotify.Write { log.Printf("file modified:" + event.Name) LoadDict() } case err := <-watcher.Errors: log.Fatal(err) } } }() err = watcher.Add(path) if err != nil { log.Fatal(err) } <-done }
func main() { file := "file.txt" r := gin.Default() m := melody.New() w, _ := fsnotify.NewWatcher() r.GET("/", func(c *gin.Context) { http.ServeFile(c.Writer, c.Request, "index.html") }) r.GET("/ws", func(c *gin.Context) { m.HandleRequest(c.Writer, c.Request) }) m.HandleConnect(func(s *melody.Session) { content, _ := ioutil.ReadFile(file) s.Write(content) }) go func() { for { ev := <-w.Events if ev.Op == fsnotify.Write { content, _ := ioutil.ReadFile(ev.Name) m.Broadcast(content) } } }() w.Add(file) r.Run(":5000") }
func init() { // in snappy, we default to using the snappy data path snappDataPath := os.Getenv("SNAPP_APP_DATA_PATH") if snappDataPath != "" { dataPath = snappDataPath } MustRefresh() if Bool(false, "dumpConfig") { spew.Dump(GetAll(false)) } go func() { watcher, err := fsnotify.NewWatcher() if err != nil { panic("Failed to create watcher: " + err.Error()) } watcher.Add(dataPath + "/etc/opt/ninja") for { select { case ev := <-watcher.Events: log.Infof("Config updated: %s", ev.Name) MustRefresh() case err := <-watcher.Errors: log.Warningf("Config Watcher error: %s", err) } } }() }
func Watch() { watcher, _ = fsnotify.NewWatcher() // Listen watched file change event go func() { for { select { case event := <-watcher.Events: if event.Op == fsnotify.Write { // Handle when file change Build() } case err := <-watcher.Errors: Log(err.Error()) } } }() var dirs = []string{"source"} for _, source := range dirs { dirPath := filepath.Join(rootPath, source) filepath.Walk(dirPath, func(path string, f os.FileInfo, err error) error { if f.IsDir() { // Defer watcher.Close() if err := watcher.Add(path); err != nil { Log(err.Error()) } } return nil }) } }
func main() { watchr, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } stopChannel := make(chan os.Signal, 1) wd, err := os.Getwd() if err != nil { log.Fatal(err) } log.Printf("watching directory %s \n", wd) err = watchr.Add(wd) if err != nil { log.Fatal(err) } signal.Notify(stopChannel, syscall.SIGINT, syscall.SIGTERM) for { select { case ev := <-watchr.Events: log.Println("event: ", ev) case err := <-watchr.Errors: log.Println("error: ", err) case <-stopChannel: log.Println("Exiting...") watchr.Close() os.Exit(1) } } }
func ExampleNewWatcher() { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event := <-watcher.Events: log.Println("event:", event) if event.Op&fsnotify.Write == fsnotify.Write { log.Println("modified file:", event.Name) } case err := <-watcher.Errors: log.Println("error:", err) } } }() err = watcher.Add("/tmp/foo") if err != nil { log.Fatal(err) } <-done }
func ExampleNewWatcher() { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event := <-watcher.Events: if event.Op&fsnotify.Create == fsnotify.Create { log.Println("added file:", event.Name) SortDates() } case err := <-watcher.Errors: log.Println("error:", err) } } }() err = watcher.Add("/Users/dhafer/camera") if err != nil { log.Fatal(err) } <-done }
func main() { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool, 1) go func() { for { select { case event := <-watcher.Events: // fmt.Println("event:", event) if event.Op&fsnotify.Write == fsnotify.Write { log.Println("modified file:", event.Name) } case err := <-watcher.Errors: log.Println("error:", err) } } }() path, _ := os.Getwd() err = watcher.Add(path) if err != nil { log.Fatal(err) } <-done }
func startWatcher() synchronization { w, err := fsnotify.NewWatcher() if err != nil { log.Fatalf("Could not create watcher: %v", err) } stop := make(chan struct{}) newBin := make(chan struct{}) go func() { Loop: for { select { case evt := <-w.Events: if evt.Op&fsnotify.Create == fsnotify.Create { log.Printf("New binary found. Preparing to shutdown.") close(newBin) } case err := <-w.Errors: log.Fatalf("File watcher error occurred: %v", err) case <-stop: w.Close() break Loop } } }() w.Add(config.watchDir) return synchronization{newBinary: newBin, stopWatcher: stop} }
func fileWatcher(ch chan string) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() err = watcher.Add(filepath.Dir(targetFileName)) if err != nil { log.Fatal(err) } for { select { case event := <-watcher.Events: if event.Name != targetFileName { continue } if event.Op&fsnotify.Write != fsnotify.Write && event.Op&fsnotify.Create != fsnotify.Create { continue } log.Println("modified file:", event, event.Name) output, _ := getContentString(event.Name) ch <- output case err := <-watcher.Errors: log.Println("error:", err) } } }
func newWatcher(a *Aster) (*Watcher, error) { fsw, err := fsnotify.NewWatcher() if err != nil { return nil, err } err = filepath.Walk(".", func(path string, fi os.FileInfo, err error) error { if err != nil || !fi.IsDir() { return err } if a.ignore.Match(path) { return filepath.SkipDir } return fsw.Add(path) }) if err != nil { fsw.Close() return nil, err } w := &Watcher{ Watcher: fsw, a: a, quit: make(chan struct{}), } return w, nil }
func runViewWatcher(views map[string]*template.Template, funcMap template.FuncMap) { viewWatcher, err := fsnotify.NewWatcher() if err != nil { panic(err) } viewWatcher.Add("views") go func() { for { select { case ev := <-viewWatcher.Events: if ev.Op&fsnotify.Write != fsnotify.Write && ev.Op&fsnotify.Chmod != fsnotify.Chmod { break } filename := strings.SplitN(ev.Name, "/", 2)[1] for templatesName, _ := range views { for _, name := range strings.Split(templatesName, ",") { if name == filename { updateTemplate(templatesName, views, funcMap) break } } } case err := <-viewWatcher.Errors: log.Printf("view watcher error: %s\n", err) } } }() }
// NewUFile 新建文件加载器 // basePath 本地文件的基本路径 // checkInterval 网络文件的最小检测间隔 func NewUFile(basePath string, checkInterval time.Duration) (*UFile, error) { basePath = strings.TrimSpace(basePath) if basePath == "" { basePath = "." } basePath, err := filepath.Abs(basePath) if err != nil { return nil, err } watcher, err := fsnotify.NewWatcher() if err != nil { return nil, err } uf := UFile{ basePath: basePath, dirs: make(map[string]int), files: make(map[string]*uFile), watcher: watcher, checkInterval: checkInterval, ResChan: make(chan *Res, 2), httpLoopAddChan: make(chan int, 1), httpLoopSleepTimer: time.NewTicker(checkInterval), } go uf.loop() return &uf, nil }
func startWatching() { if inProduction { return } watcher, err := fsnotify.NewWatcher() if err != nil { fmt.Printf("fsnotify.NewWather() failed with %s\n", err) return } go watchChanges(watcher) dirs := store.GetDirsToWatch() dirs = append(dirs, "blog_posts") for _, dir := range dirs { err = watcher.Add(dir) if err != nil { fmt.Printf("watcher.Add() for %s failed with %s\n", dir, err) return } else { //fmt.Printf("added watching for dir %s\n", dir) } } //watcher.Close() }
func NewWatcher(paths ...string) (changesChan chan string) { changesChan = make(chan string) doneCount := uint64(0) doneChan := make(chan bool) for _, p := range paths { watcher, err := fsnotify.NewWatcher() if err != nil { log.Printf("watcher for %q: err %v\n", p, err) continue } err = watcher.Add(p) if err != nil { log.Printf("%q error: %v\n", p, err) watcher.Close() continue } doneCount += 1 go func(w *fsnotify.Watcher, done chan bool) { defer w.Close() for { select { case event := <-w.Events: mask := event.Op if create(mask) || write(mask) || delete(mask) { changesChan <- event.Name } case err := <-w.Errors: if err != nil { log.Println("error:", err) } default: continue } } done <- true }(watcher, doneChan) } go func(done chan bool, n uint64) { fmt.Println("n", n) for i := uint64(0); i < n; i++ { <-done } close(changesChan) }(doneChan, doneCount) return }
func (fs *FileSystemImporter) Watch(opts *ImportOptions, shutdown chan struct{}) chan error { //we watch opts.Dir or if empty, string(fs), or if emtpy, nothing. dir := opts.Dir if dir == "" { dir = fs.WatchDir } out := make(chan error) fini := func() { //do nothing. <-shutdown close(out) } if dir == "" { go fini() } else { err := os.MkdirAll(dir, 0755) if err != nil { out <- err go fini() } else { go func() { watcher, err := fsnotify.NewWatcher() if err != nil { out <- err fini() return } defer watcher.Close() if err = watcher.Add(dir); err != nil { fini() return } var wg sync.WaitGroup log.Println("Watching Import Directory:", dir) for { select { case ev := <-watcher.Events: //log.Println("ImportWatch Event:", ev) //probably only need write here... if ev.Op == fsnotify.Create || ev.Op == fsnotify.Write { //new file created let's have it! fs.pendingImport(ev.Name, opts, out, &wg) } case err := <-watcher.Errors: out <- err case <-shutdown: wg.Wait() //wait for anything happening to happen close(out) return } } }() } } return out }
func watchInput() *fsnotify.Watcher { watcher, watcherr := fsnotify.NewWatcher() fatality(watcherr) adderr := watcher.Add("input/") fatality(adderr) return watcher }
func NewConfigWatcher(filePath string, onConfigChange OnChange) (configWatcher *ConfigWatcher, err error) { watcher, err := fsnotify.NewWatcher() if err != nil { return nil, err } configWatcher = &ConfigWatcher{watcher, onConfigChange, filePath, make(chan struct{})} configWatcher.Watch() return }
func initWatcher() { watcher, err := fsnotify.NewWatcher() if err != nil { mon.logger.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event := <-watcher.Events: if event.Op&fsnotify.Write == fsnotify.Write { mon.logger.Println("modified file:", event.Name) handleWatcher("MODIFY", event.Name) } else if event.Op&fsnotify.Create == fsnotify.Create { mon.logger.Println("created file:", event.Name) handleWatcher("CREATE", event.Name) } case err := <-watcher.Errors: mon.logger.Println("error:", err) } } }() go func() { for { select { case <-time.After(DEF_DELAY * time.Second): resetWatcher() } } }() for _, dir := range mon.dirs { dir = strings.TrimSpace(dir) if dir == "" { continue } l := make([]string, 0) l = append(l, dir) l, err = util.RecursiveDir(dir, l) if err != nil { mon.logger.Fatal(err) } for _, d := range l { mon.logger.Println("watcher dir: ", d) err = watcher.Add(d) if err != nil { mon.logger.Fatal(err) } } } <-done }
func (f *File) watchFile(filename string) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } f.watcher = watcher err = watcher.Add(filename) if err != nil { log.Fatal(err) } }
func Test_datapoolMonitor(t *testing.T) { var err error watcher, err = fsnotify.NewWatcher() if err != nil { l := log.Error(err) logq.LogPutqueue(l) } defer watcher.Close() AddtoMonitor("/var/lib/datahub/datahubUtest.db", "repounittest/itemunittest:tagunittestdatahubUtest.db") }
// set up the watch on the host's /etc/resolv.conf so that we can update container's // live resolv.conf when the network changes on the host func (daemon *Daemon) setupResolvconfWatcher() error { watcher, err := fsnotify.NewWatcher() if err != nil { return err } //this goroutine listens for the events on the watch we add //on the resolv.conf file on the host go func() { for { select { case event := <-watcher.Events: if event.Name == "/etc/resolv.conf" && (event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Create == fsnotify.Create) { // verify a real change happened before we go further--a file write may have happened // without an actual change to the file updatedResolvConf, newResolvConfHash, err := resolvconf.GetIfChanged() if err != nil { log.Debugf("Error retrieving updated host resolv.conf: %v", err) } else if updatedResolvConf != nil { // because the new host resolv.conf might have localhost nameservers.. updatedResolvConf, modified := resolvconf.FilterResolvDns(updatedResolvConf, daemon.config.EnableIPv6) if modified { // changes have occurred during localhost cleanup: generate an updated hash newHash, err := utils.HashData(bytes.NewReader(updatedResolvConf)) if err != nil { log.Debugf("Error generating hash of new resolv.conf: %v", err) } else { newResolvConfHash = newHash } } log.Debugf("host network resolv.conf changed--walking container list for updates") contList := daemon.containers.List() for _, container := range contList { if err := container.updateResolvConf(updatedResolvConf, newResolvConfHash); err != nil { log.Debugf("Error on resolv.conf update check for container ID: %s: %v", container.ID, err) } } } } case err := <-watcher.Errors: log.Debugf("host resolv.conf notify error: %v", err) } } }() if err := watcher.Add("/etc"); err != nil { return err } return nil }
//NewWatch 看守对象 func NewWatch() (*Watch, error) { fsnotifyWatcher, err := fsnotify.NewWatcher() if err != nil { return nil, err } w := &Watch{ watcher: fsnotifyWatcher, eventfunc: make(map[string]WatchEventFun), syncRWMutex: new(sync.RWMutex), } go w.event() return w, nil }
func newFolderWatcher(dirList []string) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer watcher.Close() done := make(chan bool) go func() { for { select { case event := <-watcher.Events: logg.LogTo(TagLog, "New Event %v", event) if event.Op&fsnotify.Chmod == fsnotify.Chmod { f, _ := os.Stat(event.Name) if isJSON(f.Name()) && !isHidden(f.Name()) { err = NewLocalDocument(event.Name, &resources) } else if !isHidden(f.Name()) { err = NewLocalAttachment(event.Name, &resources) } if err != nil { logg.LogTo(TagError, "%v", err) } else { patchFiles(resources) } } if event.Op&fsnotify.Rename == fsnotify.Rename { documentID := getDocumentID(event.Name) err := deleteDocument(documentID) if err != nil { logg.LogTo(TagError, "Error deleting document : %v", err) } } case err := <-watcher.Errors: logg.LogTo(TagError, "%v", err) } } }() for _, dir := range dirList { logg.LogTo(TagLog, "attaching watcher to %s", dir) err = watcher.Add(dir) if err != nil { logg.LogPanic("Error attaching fs watcher : %v", err) } } <-done }
func Watch() { // Listen watched file change event if watcher != nil { watcher.Close() } watcher, _ = fsnotify.NewWatcher() go func() { for { select { case event := <-watcher.Events: if event.Op == fsnotify.Write { // Handle when file change Log(event.Name) ParseGlobalConfigWrap(rootPath, true) Build() if conn != nil { if err := conn.WriteMessage(websocket.TextMessage, []byte("change")); err != nil { Warn(err.Error()) } } } case err := <-watcher.Errors: Warn(err.Error()) } } }() var dirs = []string{ filepath.Join(rootPath, "source"), filepath.Join(themePath, "bundle"), } var files = []string{ filepath.Join(rootPath, "config.yml"), filepath.Join(themePath), } for _, source := range dirs { symwalk.Walk(source, func(path string, f os.FileInfo, err error) error { if f.IsDir() { if err := watcher.Add(path); err != nil { Warn(err.Error()) } } return nil }) } for _, source := range files { if err := watcher.Add(source); err != nil { Warn(err.Error()) } } }
// WatchService start a watcher on the given service. // Execute preHook right away and after each event on the target service. // Execute postHook only after the event. func WatchService(preHook, postHook func(ip string), service, discoveryPath string, stopChan <-chan struct{}) { if discoveryPath == "" || service == "" || preHook == nil || stopChan == nil { logrus.Errorf("WatchService fail for %q: preHook, service, discoveryPath and stopChan are mandatory", service) return } watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } defer func() { _ = watcher.Close() }() // Best effort. watcher.Add(discoveryPath) path := path.Join(discoveryPath, service) ticker := time.NewTicker(1 * time.Minute) defer ticker.Stop() for { ip, err := LookupLocalServiceIP(service, discoveryPath) if err != nil { // TODO: handle error. } preHook(ip) wait: /// Wait for an event select { case <-ticker.C: case <-stopChan: return case event, open := <-watcher.Events: if !open { return } if event.Name != path { goto wait } case err, open := <-watcher.Errors: if !open { return } // TODO: handle errors. _ = err } // TODO: create a post hook? (for Close()) if postHook != nil { postHook(ip) } } }
func addFileWatcher(mediaType, prefix, path string) (*fsnotify.Watcher, error) { fullpath := filepath.Join(statemanager.BaseFilePath(), prefix, path) os.MkdirAll(fullpath, 0775) watcher, err := fsnotify.NewWatcher() if err != nil { return nil, err } err = watcher.Add(fullpath) if err != nil { watcher.Close() return nil, err } f, err := os.Open(fullpath) if err != nil { return nil, err } names, err := f.Readdirnames(-1) f.Close() for _, name := range names { short := filepath.Base(name) full := filepath.Join(path, short) statemanager.StateUpdateString(fmt.Sprintf("Media.Type(%v).File(%v)", mediaType, full), short) } go func() { for { select { case event := <-watcher.Events: short := filepath.Base(event.Name) full := filepath.Join(path, short) if event.Op&fsnotify.Create == fsnotify.Create { statemanager.StateUpdateString(fmt.Sprintf("Media.Type(%v).File(%v)", mediaType, full), short) } else if event.Op&fsnotify.Rename == fsnotify.Rename { statemanager.StateDelete(fmt.Sprintf("Media.Type(%v).File(%v)", mediaType, full)) } else if event.Op&fsnotify.Remove == fsnotify.Remove { statemanager.StateDelete(fmt.Sprintf("Media.Type(%v).File(%v)", mediaType, full)) } case err := <-watcher.Errors: log.Println("error:", err) } } }() return watcher, nil }