added debounce (#11)
This commit is contained in:
parent
deb6808c75
commit
6b8d872d68
2 changed files with 60 additions and 23 deletions
|
@ -89,32 +89,10 @@ func (a *App) Run() error {
|
||||||
}
|
}
|
||||||
a.Watcher.Add(p.Path)
|
a.Watcher.Add(p.Path)
|
||||||
}
|
}
|
||||||
go a.watch()
|
go startWatcher(a)
|
||||||
return http.Serve(a.Listener, a.Router)
|
return http.Serve(a.Listener, a.Router)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch the library path and update Library with changes.
|
|
||||||
func (a *App) watch() {
|
|
||||||
for {
|
|
||||||
e, ok := <-a.Watcher.Events
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if e.Op&fsnotify.Create > 0 {
|
|
||||||
// add new files to library
|
|
||||||
a.Library.Add(e.Name)
|
|
||||||
} else if e.Op&(fsnotify.Write|fsnotify.Chmod) > 0 {
|
|
||||||
// writes and chmods should remove old file before adding again
|
|
||||||
a.Library.Remove(e.Name)
|
|
||||||
a.Library.Add(e.Name)
|
|
||||||
} else if e.Op&(fsnotify.Remove|fsnotify.Rename) > 0 {
|
|
||||||
// remove and rename just remove file
|
|
||||||
// fsnotify will signal a Create event with the new file name
|
|
||||||
a.Library.Remove(e.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP handler for /
|
// HTTP handler for /
|
||||||
func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
|
func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("/")
|
log.Printf("/")
|
||||||
|
|
59
pkg/app/watcher.go
Normal file
59
pkg/app/watcher.go
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue