Added inotify watcher for restarting slideshow when files are changed/deleted/added
This commit is contained in:
parent
b608f61506
commit
88b60f2df0
3
cmd/inotify/README.md
Normal file
3
cmd/inotify/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# inotify
|
||||||
|
|
||||||
|
This is the main source code for the inotify watcher that restarts the PiFrame slide show when files have changed (add/remove/etc).
|
68
cmd/inotify/inotify.go
Normal file
68
cmd/inotify/inotify.go
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os/exec"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/dietsche/rfsnotify"
|
||||||
|
|
||||||
|
"git.kemonine.info/PiFrame/watchdog"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CMD_SYSTEMCTL = "/usr/bin/systemctl"
|
||||||
|
PATH_PICTURES = "/tank/pictures"
|
||||||
|
TIMEOUT = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Create watchdog timer that restarts fim.service on timeout
|
||||||
|
watchdog := watchdog.New(TIMEOUT, func() {
|
||||||
|
err := exec.Command(CMD_SYSTEMCTL, "restart", "fim.service").Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error running %s : %s", CMD_SYSTEMCTL, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
watchdog.DeferredStart()
|
||||||
|
|
||||||
|
// Create fswatcher
|
||||||
|
watcher, err := rfsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error setting up rfsnotify")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure we clean stuff up no matter what
|
||||||
|
defer watcher.Close()
|
||||||
|
|
||||||
|
// Setup goroutine and listen for events
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event, ok := <-watcher.Events:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Print out event (this is where logic will go eventually))
|
||||||
|
log.Printf("event: %#v\n", event)
|
||||||
|
// [Re]Start timer to restart slideshow after the fs events die down
|
||||||
|
watchdog.Kick()
|
||||||
|
case err, ok := <-watcher.Errors:
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("Error: ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Setup paths to watch
|
||||||
|
err = watcher.AddRecursive(PATH_PICTURES)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error setting up recursive watch of %s", PATH_PICTURES)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drain done channel...
|
||||||
|
<-done
|
||||||
|
}
|
3
watchdog/README.md
Normal file
3
watchdog/README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# watchdog
|
||||||
|
|
||||||
|
A very simple watchdog timer implementation. Borrowed from [here](https://codereview.stackexchange.com/questions/144273/watchdog-in-golang) and tweaked slightly.
|
41
watchdog/watchdog.go
Normal file
41
watchdog/watchdog.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Adapted from https://codereview.stackexchange.com/questions/144273/watchdog-in-golang
|
||||||
|
|
||||||
|
package watchdog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type watchdog struct {
|
||||||
|
interval time.Duration
|
||||||
|
callback func()
|
||||||
|
timer *time.Timer
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(interval time.Duration, callback func()) *watchdog {
|
||||||
|
w := watchdog{
|
||||||
|
interval: interval,
|
||||||
|
callback: callback,
|
||||||
|
timer: nil,
|
||||||
|
}
|
||||||
|
return &w
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *watchdog) Start() {
|
||||||
|
w.timer = time.AfterFunc(w.interval, w.callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to allow the watchdog to be started by a call to Kick directly
|
||||||
|
func (w *watchdog) DeferredStart() {
|
||||||
|
w.Start()
|
||||||
|
w.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *watchdog) Stop() {
|
||||||
|
w.timer.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *watchdog) Kick() {
|
||||||
|
w.Stop()
|
||||||
|
w.timer.Reset(w.interval)
|
||||||
|
}
|
Loading…
Reference in a new issue