fix issue of failing in folder watching with no recursive option for package gfsnotify

This commit is contained in:
John Guo 2021-05-17 13:43:36 +08:00
parent a757fbd37d
commit 522f6cb455
3 changed files with 70 additions and 45 deletions

View File

@ -91,8 +91,8 @@ func New() (*Watcher, error) {
intlog.Printf("New watcher failed: %v", err)
return nil, err
}
w.startWatchLoop()
w.startEventLoop()
w.watchLoop()
w.eventLoop()
return w, nil
}

View File

@ -11,8 +11,8 @@ import (
"github.com/gogf/gf/internal/intlog"
)
// startWatchLoop starts the loop for event listening fro underlying inotify monitor.
func (w *Watcher) startWatchLoop() {
// watchLoop starts the loop for event listening fro underlying inotify monitor.
func (w *Watcher) watchLoop() {
go func() {
for {
select {
@ -40,47 +40,8 @@ func (w *Watcher) startWatchLoop() {
}()
}
// getCallbacks searches and returns all callbacks with given <path>.
// It also searches its parent for callbacks if they're recursive.
func (w *Watcher) getCallbacks(path string) (callbacks []*Callback) {
// Firstly add the callbacks of itself.
if v := w.callbacks.Get(path); v != nil {
for _, v := range v.(*glist.List).FrontAll() {
callback := v.(*Callback)
callbacks = append(callbacks, callback)
}
}
// Secondly searches its parent for callbacks.
dirPath := fileDir(path)
if v := w.callbacks.Get(dirPath); v != nil {
for _, v := range v.(*glist.List).FrontAll() {
callback := v.(*Callback)
if callback.recursive {
callbacks = append(callbacks, callback)
}
}
}
// Lastly searches the parent recursively for callbacks.
for {
parentDirPath := fileDir(dirPath)
if parentDirPath == dirPath {
break
}
if v := w.callbacks.Get(parentDirPath); v != nil {
for _, v := range v.(*glist.List).FrontAll() {
callback := v.(*Callback)
if callback.recursive {
callbacks = append(callbacks, callback)
}
}
}
dirPath = parentDirPath
}
return
}
// startEventLoop is the core event handler.
func (w *Watcher) startEventLoop() {
// eventLoop is the core event handler.
func (w *Watcher) eventLoop() {
go func() {
for {
if v := w.events.Pop(); v != nil {
@ -171,3 +132,42 @@ func (w *Watcher) startEventLoop() {
}
}()
}
// getCallbacks searches and returns all callbacks with given <path>.
// It also searches its parents for callbacks if they're recursive.
func (w *Watcher) getCallbacks(path string) (callbacks []*Callback) {
// Firstly add the callbacks of itself.
if v := w.callbacks.Get(path); v != nil {
for _, v := range v.(*glist.List).FrontAll() {
callback := v.(*Callback)
callbacks = append(callbacks, callback)
}
}
// Secondly searches its direct parent for callbacks.
// It is special handling here, which is the different between `recursive` and `not recursive` logic
// for direct parent folder of `path` that events are from.
dirPath := fileDir(path)
if v := w.callbacks.Get(dirPath); v != nil {
for _, v := range v.(*glist.List).FrontAll() {
callback := v.(*Callback)
callbacks = append(callbacks, callback)
}
}
// Lastly searches all the parents of directory of `path` recursively for callbacks.
for {
parentDirPath := fileDir(dirPath)
if parentDirPath == dirPath {
break
}
if v := w.callbacks.Get(parentDirPath); v != nil {
for _, v := range v.(*glist.List).FrontAll() {
callback := v.(*Callback)
if callback.recursive {
callbacks = append(callbacks, callback)
}
}
}
dirPath = parentDirPath
}
return
}

View File

@ -7,6 +7,7 @@
package gfsnotify_test
import (
"github.com/gogf/gf/container/garray"
"testing"
"time"
@ -191,3 +192,27 @@ func TestWatcher_Callback2(t *testing.T) {
t.Assert(v2.Val(), 2)
})
}
func TestWatcher_WatchFolderWithoutRecursively(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
var (
err error
array = garray.New(true)
dirPath = gfile.TempDir(gtime.TimestampNanoStr())
)
err = gfile.Mkdir(dirPath)
t.AssertNil(err)
_, err = gfsnotify.Add(dirPath, func(event *gfsnotify.Event) {
array.Append(1)
}, false)
t.AssertNil(err)
time.Sleep(time.Millisecond * 100)
t.Assert(array.Len(), 0)
err = gfile.PutContents(gfile.Join(dirPath, "1"), "1")
t.AssertNil(err)
time.Sleep(time.Millisecond * 100)
t.Assert(array.Len(), 1)
})
}