rjeczalik / notify

File system event notification library on steroids.
MIT License
903 stars 128 forks source link

notify.ALL does not have event for file on 'cp -R a/ ./b' #88

Open timesking opened 8 years ago

timesking commented 8 years ago

Hi,

I tried to monitor file changes, just like what https://github.com/rekby/etcddir/blob/master/main.go did.

func fileMon(path string, bus chan fileChangeEvent) {
    // 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.
    c := make(chan notify.EventInfo, 1)

    // Set up a watchpoint listening on events within current working directory.
    // Dispatch each create and remove events separately to c.
    if err := notify.Watch(path+"/...", c, notify.All); err != nil {
        log.Fatal(err)
    }
    defer notify.Stop(c)

    // Block until an event is received.
    for {
        event := <-c
        fstat, err := os.Lstat(event.Path())
        if os.IsNotExist(err) {
            bus <- fileChangeEvent{Path: event.Path(), IsRemoved: true}
            continue
        }

        if err != nil {
            log.Println(err)
            continue
        }

        if fstat.IsDir() {
            bus <- fileChangeEvent{Path: event.Path(), IsDir: true}
            continue
        }

        content, err := ioutil.ReadFile(event.Path())
        if err != nil {
            log.Println(err)
        }
        bus <- fileChangeEvent{Path: event.Path(), Content: content}
    }
}

buf if folder a has as structure like this

/a
   /b/1.txt
   /b/2.tst

when I tried to mkdir /c && cp -R /a/* /c, the c folder will have a tree:

/c
   /b/1.txt
   /b/2.tst

but there is no event about 1.txt and 2.txt.

Could you help me to figure it out what's wront?

rjeczalik commented 8 years ago

Hey @timesking, thanks for reporting. What platform are you using?

c := make(chan notify.EventInfo, 1)

You may want to use a bigger buffer here if you expect larger volume of notifications.

timesking commented 8 years ago

I have changed to 1000, but nothing help

The system is

Linux ip-10-33-1-5 3.14.35-28.38.amzn1.x86_64 #1 SMP Wed Mar 11 22:50:37 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
rjeczalik commented 8 years ago

You need to provide me with full example, there might be too many loose ends (blocking send on bus?).

(hint: for debug logging you just compile your cmd with -tags debug)

ppknap commented 8 years ago

Hi guys!

@timesking I assume that want to receive create events for /c/b/1.txt and /c/b/2.txt. The problem is that these events are triggered before we create watchers for c and b directories. Because inotify is not recursive, we must set watchers manually and we are just not fast enough to catch all events triggered before we do so...

The best solution is to rescan all subfolders after we set the watcher. Notify was designed to handle such cases(non-recursive trees) but I don't know if it was implemented or postponed.

More info here: http://linux.die.net/man/7/inotify

If monitoring an entire directory subtree, and a new subdirectory is created in 
that tree, be aware that by the time you create a watch for the new subdirectory,
new files may already have been created in the subdirectory. Therefore, you may
want to scan the contents of the subdirectory immediately after adding the watch.
timesking commented 8 years ago

Oh, Thanks @ppknap, it is really helpful. I will make a try with scan later.