github.com/cs3org/reva/v2@v2.27.7/pkg/storage/fs/posix/tree/inotifywatcher.go (about) 1 // Copyright 2018-2024 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package tree 20 21 import ( 22 "fmt" 23 24 "github.com/pablodz/inotifywaitgo/inotifywaitgo" 25 "github.com/rs/zerolog" 26 ) 27 28 type InotifyWatcher struct { 29 tree *Tree 30 log *zerolog.Logger 31 } 32 33 func NewInotifyWatcher(tree *Tree, log *zerolog.Logger) *InotifyWatcher { 34 return &InotifyWatcher{ 35 tree: tree, 36 log: log, 37 } 38 } 39 40 func (iw *InotifyWatcher) Watch(path string) { 41 events := make(chan inotifywaitgo.FileEvent) 42 errors := make(chan error) 43 44 go inotifywaitgo.WatchPath(&inotifywaitgo.Settings{ 45 Dir: path, 46 FileEvents: events, 47 ErrorChan: errors, 48 KillOthers: true, 49 Options: &inotifywaitgo.Options{ 50 Recursive: true, 51 Events: []inotifywaitgo.EVENT{ 52 inotifywaitgo.CREATE, 53 inotifywaitgo.MOVED_TO, 54 inotifywaitgo.MOVED_FROM, 55 inotifywaitgo.CLOSE_WRITE, 56 inotifywaitgo.DELETE, 57 }, 58 Monitor: true, 59 }, 60 Verbose: false, 61 }) 62 63 for { 64 select { 65 case event := <-events: 66 if isLockFile(event.Filename) || isTrash(event.Filename) || iw.tree.isUpload(event.Filename) { 67 continue 68 } 69 for _, e := range event.Events { 70 go func() { 71 var err error 72 switch e { 73 case inotifywaitgo.DELETE: 74 err = iw.tree.Scan(event.Filename, ActionDelete, event.IsDir) 75 case inotifywaitgo.MOVED_FROM: 76 err = iw.tree.Scan(event.Filename, ActionMoveFrom, event.IsDir) 77 case inotifywaitgo.CREATE, inotifywaitgo.MOVED_TO: 78 err = iw.tree.Scan(event.Filename, ActionCreate, event.IsDir) 79 case inotifywaitgo.CLOSE_WRITE: 80 err = iw.tree.Scan(event.Filename, ActionUpdate, event.IsDir) 81 case inotifywaitgo.CLOSE: 82 // ignore, already handled by CLOSE_WRITE 83 default: 84 iw.log.Warn().Interface("event", event).Msg("unhandled event") 85 return 86 } 87 if err != nil { 88 iw.log.Error().Err(err).Str("path", event.Filename).Msg("error scanning file") 89 } 90 }() 91 } 92 93 case err := <-errors: 94 switch err.Error() { 95 case inotifywaitgo.NOT_INSTALLED: 96 panic("Error: inotifywait is not installed") 97 case inotifywaitgo.INVALID_EVENT: 98 // ignore 99 default: 100 fmt.Printf("Error: %s\n", err) 101 } 102 } 103 } 104 }