From 6b8d872d680d019827cc45881186cce3f83f764a Mon Sep 17 00:00:00 2001 From: davy wybiral Date: Wed, 3 Jul 2019 14:44:31 -0500 Subject: added debounce (#11) --- pkg/app/watcher.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 pkg/app/watcher.go (limited to 'pkg/app/watcher.go') diff --git a/pkg/app/watcher.go b/pkg/app/watcher.go new file mode 100644 index 0000000..2d7a761 --- /dev/null +++ b/pkg/app/watcher.go @@ -0,0 +1,59 @@ +package app + +import ( + "time" + + fs "github.com/fsnotify/fsnotify" +) + +// This is the amount of time to wait after changes before reacting to them. +// Debounce is done because moving files into the watched directories causes +// many rapid "Write" events to fire which would cause excessive Remove/Add +// method calls on the Library. To avoid this we accumulate the changes and +// only perform them once the events have stopped for this amount of time. +const debounceTimeout = time.Second * 5 + +// create, write, and chmod all require an add event +const addFlags = fs.Create | fs.Write | fs.Chmod + +// remove, rename, write, and chmod all require a remove event +const removeFlags = fs.Remove | fs.Rename | fs.Write | fs.Chmod + +// watch library paths and update Library with changes. +func startWatcher(a *App) { + timer := time.NewTimer(debounceTimeout) + addEvents := make(map[string]struct{}) + removeEvents := make(map[string]struct{}) + for { + select { + case e := <-a.Watcher.Events: + if e.Op&removeFlags > 0 { + removeEvents[e.Name] = struct{}{} + } + if e.Op&addFlags > 0 { + addEvents[e.Name] = struct{}{} + } + // reset timer + timer.Reset(debounceTimeout) + case <-timer.C: + // handle remove events first + if len(removeEvents) > 0 { + for p := range removeEvents { + a.Library.Remove(p) + } + // clear map + removeEvents = make(map[string]struct{}) + } + // then handle add events + if len(addEvents) > 0 { + for p := range addEvents { + a.Library.Add(p) + } + // clear map + addEvents = make(map[string]struct{}) + } + // reset timer + timer.Reset(debounceTimeout) + } + } +} -- cgit v1.2.3