diff --git a/go.mod b/go.mod index 728c731707854..f2dd349c72d42 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,6 @@ require ( github.com/emirpasic/gods v1.18.1 github.com/ethantkoenig/rupture v1.0.1 github.com/felixge/fgprof v0.9.2 - github.com/fsnotify/fsnotify v1.5.4 github.com/gliderlabs/ssh v0.3.4 github.com/go-ap/activitypub v0.0.0-20220615144428-48208c70483b github.com/go-ap/jsonld v0.0.0-20220615144122-1d862b15410d @@ -82,6 +81,7 @@ require ( github.com/sergi/go-diff v1.2.0 github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 github.com/stretchr/testify v1.7.1 + github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 github.com/syndtr/goleveldb v1.0.0 github.com/tstranex/u2f v1.0.0 github.com/unrolled/render v1.4.1 @@ -161,6 +161,7 @@ require ( github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fullstorydev/grpcurl v1.8.1 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/go-ap/errors v0.0.0-20220615144307-e8bc4a40ae9f // indirect diff --git a/go.sum b/go.sum index 103206980776e..bdd4461a3ea22 100644 --- a/go.sum +++ b/go.sum @@ -1474,6 +1474,8 @@ github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMT github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 h1:F4snRP//nIuTTW9LYEzVH4HVwDG9T3M4t8y/2nqMbiY= +github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2/go.mod h1:J0q59IWjLtpRIJulohwqEZvjzwOfTEPp8SVhDJl+y0Y= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= @@ -1840,6 +1842,7 @@ golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/modules/watcher/watcher.go b/modules/watcher/watcher.go index 5136c2dee8cc4..4b288600db253 100644 --- a/modules/watcher/watcher.go +++ b/modules/watcher/watcher.go @@ -12,7 +12,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" - "github.com/fsnotify/fsnotify" + "github.com/syncthing/notify" ) type CreateWatcherOpts struct { @@ -39,21 +39,22 @@ func run(ctx context.Context, desc string, opts *CreateWatcherOpts) { log.Trace("Watcher loop starting for %s", desc) defer log.Trace("Watcher loop ended for %s", desc) - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Error("Unable to create watcher for %s: %v", desc, err) - return - } + // Make the channel buffered to ensure no event is dropped. Notify will drop + // an event if the receiver is not able to keep up the sending pace. + events := make(chan notify.EventInfo, 1) + if err := opts.PathsCallback(func(path, _ string, _ fs.DirEntry, err error) error { if err != nil && !os.IsNotExist(err) { return err } log.Trace("Watcher: %s watching %q", desc, path) - _ = watcher.Add(path) + if err := notify.Watch(path, events, notify.All); err != nil { + log.Trace("Watcher: %s unable to watch %q: error %v", desc, path, err) + } return nil }); err != nil { log.Error("Unable to create watcher for %s: %v", desc, err) - _ = watcher.Close() + notify.Stop(events) return } @@ -61,39 +62,34 @@ func run(ctx context.Context, desc string, opts *CreateWatcherOpts) { for { select { - case event, ok := <-watcher.Events: + case event, ok := <-events: if !ok { - _ = watcher.Close() + notify.Stop(events) return } + log.Debug("Watched file for %s had event: %v", desc, event) - case err, ok := <-watcher.Errors: - if !ok { - _ = watcher.Close() - return - } - log.Error("Error whilst watching files for %s: %v", desc, err) case <-ctx.Done(): - _ = watcher.Close() + notify.Stop(events) return } // Recreate the watcher - only call the BetweenCallback after the new watcher is set-up - _ = watcher.Close() - watcher, err = fsnotify.NewWatcher() - if err != nil { - log.Error("Unable to create watcher for %s: %v", desc, err) - return - } + notify.Stop(events) + events = make(chan notify.EventInfo, 1) + if err := opts.PathsCallback(func(path, _ string, _ fs.DirEntry, err error) error { if err != nil { return err } - _ = watcher.Add(path) + log.Trace("Watcher: %s watching %q", desc, path) + if err := notify.Watch(path, events, notify.All); err != nil { + log.Trace("Watcher: %s unable to watch %q: error %v", desc, path, err) + } return nil }); err != nil { log.Error("Unable to create watcher for %s: %v", desc, err) - _ = watcher.Close() + notify.Stop(events) return }