summaryrefslogtreecommitdiff
path: root/app/watcher.go
diff options
context:
space:
mode:
authorJames Mills <prologic@shortcircuit.net.au>2020-03-21 09:55:06 +1000
committerJames Mills <prologic@shortcircuit.net.au>2020-03-21 09:55:06 +1000
commit4dae45a68ff1ff32a251a5835b2a2723ae125d1c (patch)
treeb3abe641f39f50ac444aee2bb617d7b4ab44187d /app/watcher.go
parent76fa613b7eaf1c8626d2a51901c623af7bf1a665 (diff)
Restructured source code layout, Added rice support for templates and static assets
Diffstat (limited to 'app/watcher.go')
-rw-r--r--app/watcher.go63
1 files changed, 63 insertions, 0 deletions
diff --git a/app/watcher.go b/app/watcher.go
new file mode 100644
index 0000000..74db715
--- /dev/null
+++ b/app/watcher.go
@@ -0,0 +1,63 @@
+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:
+ eventCount := len(removeEvents) + len(addEvents)
+ // 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{})
+ }
+ if eventCount > 0 {
+ buildFeed(a)
+ }
+ // reset timer
+ timer.Reset(debounceTimeout)
+ }
+ }
+}