av/cmd/vidforward/watcher.go

80 lines
2.1 KiB
Go
Raw Normal View History

/*
DESCRIPTION
watcher.go provides a tool for watching a file for modifications and
performing an action when the file is modified.
AUTHORS
Saxon A. Nelson-Milton <saxon@ausocean.org>
LICENSE
Copyright (C) 2022 the Australian Ocean Lab (AusOcean)
It is free software: you can redistribute it and/or modify them
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
*/
package main
import (
"fmt"
"path"
"bitbucket.org/ausocean/utils/logging"
"github.com/fsnotify/fsnotify"
)
// watchFile watches a file for modifications and calls onWrite when the file
// is modified. Technically, the directory is watched instead of the file.
// This is because watching the file itself will cause problems if changes
// are done atomically.
// See fsnotify documentation:
// https://godocs.io/github.com/fsnotify/fsnotify#hdr-Watching_files
func watchFile(file string, onWrite func(), l logging.Logger) error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return fmt.Errorf("could not create watcher: %w", err)
}
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
l.Warning("watcher events chan closed, terminating")
return
}
if event.Op&fsnotify.Write == fsnotify.Write && event.Name == file {
l.Info("file modification event", "file", file)
onWrite()
}
case err, ok := <-watcher.Errors:
if !ok {
l.Warning("watcher error chan closed, terminating")
return
}
l.Error("file watcher error", "error", err)
}
}
}()
// Watch the directory over the file.
err = watcher.Add(path.Dir(file))
if err != nil {
return fmt.Errorf("could not add file %s to watcher: %w", file, err)
}
return nil
}