Files
pspy/internal/fswatcher/setup.go
2018-03-12 08:58:01 +01:00

74 lines
1.7 KiB
Go

package fswatcher
import (
"fmt"
"github.com/dominicbreuker/pspy/internal/fswatcher/inotify"
isys "github.com/dominicbreuker/pspy/internal/fswatcher/inotify/sys"
"github.com/dominicbreuker/pspy/internal/fswatcher/walker"
)
type InotifyWatcher struct {
i *inotify.Inotify
}
func (iw *InotifyWatcher) Close() {
iw.i.Close()
}
func NewInotifyWatcher() (*InotifyWatcher, error) {
i, err := inotify.NewInotify(&isys.InotifySyscallsUNIX{})
if err != nil {
return nil, fmt.Errorf("setting up inotify: %v", err)
}
return &InotifyWatcher{
i: i,
}, nil
}
func (iw *InotifyWatcher) Setup(rdirs, dirs []string, errCh chan error) (chan struct{}, chan string, error) {
maxWatchers, err := getLimit()
if err != nil {
errCh <- fmt.Errorf("Can't get inotify watcher limit...: %v\n", err)
maxWatchers = -1
}
for _, dir := range rdirs {
addWatchers(dir, -1, iw.i, maxWatchers, errCh)
}
for _, dir := range dirs {
addWatchers(dir, 0, iw.i, maxWatchers, errCh)
}
triggerCh := make(chan struct{})
dataCh := make(chan []byte)
go Observe(iw.i, triggerCh, dataCh, errCh)
eventCh := make(chan string)
go parseEvents(iw.i, dataCh, eventCh, errCh)
return triggerCh, eventCh, nil
}
func addWatchers(dir string, depth int, i *inotify.Inotify, maxWatchers int, errCh chan error) {
dirCh, walkErrCh, doneCh := walker.Walk(dir, depth)
loop:
for {
if maxWatchers > 0 && i.NumWatchers() >= maxWatchers {
close(doneCh)
break loop
}
select {
case err := <-walkErrCh:
errCh <- fmt.Errorf("adding inotift watchers: %v", err)
case dir, ok := <-dirCh:
if !ok {
break loop
}
if err := i.Watch(dir); err != nil {
errCh <- fmt.Errorf("Can't create watcher: %v", err)
}
}
}
}