diff --git a/utils/file.go b/utils/file.go
index 14e8cceea..760ca4e1a 100644
--- a/utils/file.go
+++ b/utils/file.go
@@ -45,28 +45,30 @@ func watchDir(dirPath string, f func(itmID string) error, sysID string,
return
}
+// watch monitors a directory for file creation events and processes them asynchronously.
func watch(dirPath, sysID string, f func(itmID string) error,
- watcher *fsnotify.Watcher, stopWatching chan struct{}) (err error) {
+ watcher *fsnotify.Watcher, stopWatching chan struct{}) error {
defer watcher.Close()
for {
select {
case <-stopWatching:
Logger.Info(fmt.Sprintf("<%s> stop watching path <%s>", sysID, dirPath))
- return
+ return nil
case ev := <-watcher.Events:
if ev.Op&fsnotify.Create == fsnotify.Create {
- go func() { //Enable async processing here so we can simultaneously process files
- if err = f(filepath.Base(ev.Name)); err != nil {
+ // Process files asynchronously to prevent blocking the watcher.
+ go func() {
+ if err := f(filepath.Base(ev.Name)); err != nil {
Logger.Warning(fmt.Sprintf("<%s> processing path <%s>, error: <%s>",
sysID, ev.Name, err.Error()))
}
}()
}
- case err = <-watcher.Errors:
- Logger.Err(
- fmt.Sprintf("<%s> watching path <%s>, error: <%s>, exiting!",
- sysID, dirPath, err.Error()))
- return
+ case err := <-watcher.Errors:
+ Logger.Err(fmt.Sprintf(
+ "<%s> watching path <%s>, error: <%s>, exiting!",
+ sysID, dirPath, err.Error()))
+ return err
}
}
}
diff --git a/utils/file_it_test.go b/utils/file_it_test.go
index 58b4033ab..8c141a77f 100644
--- a/utils/file_it_test.go
+++ b/utils/file_it_test.go
@@ -22,9 +22,12 @@ along with this program. If not, see
package utils
import (
+ "bytes"
"fmt"
+ "log"
"os"
"path"
+ "strings"
"testing"
"github.com/fsnotify/fsnotify"
@@ -63,6 +66,14 @@ func testWatchWatcherError(t *testing.T) {
}
func testWatchWatcherEvents(t *testing.T) {
+ Logger.SetLogLevel(4)
+ Logger.SetSyslog(nil)
+ buf := new(bytes.Buffer)
+ log.SetOutput(buf)
+ t.Cleanup(func() {
+ Logger.SetLogLevel(0)
+ log.SetOutput(os.Stderr)
+ })
watcher, err := fsnotify.NewWatcher()
if err != nil {
t.Fatal(err)
@@ -82,9 +93,12 @@ func testWatchWatcherEvents(t *testing.T) {
}
return fmt.Errorf("Can't match path")
}
- expected := "Can't match path"
- if err := watch(EmptyString, EmptyString, f, watcher, stopWatching); err == nil || err.Error() != expected {
- t.Errorf("Expected %+v, received %+v", expected, err)
+ if err := watch(EmptyString, EmptyString, f, watcher, stopWatching); err != nil {
+ t.Error(err)
+ }
+ expLog := `[WARNING] <> processing path , error: `
+ if !strings.Contains(buf.String(), expLog) {
+ t.Errorf("expected %q to be present, received:\n%s", expLog, buf.String())
}
}