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)
|
||||
}
|
||||
go a.watch()
|
||||
go startWatcher(a)
|
||||
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 /
|
||||
func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
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