Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot watch non-existent files #49

Closed
tve opened this issue Oct 20, 2014 · 9 comments · Fixed by #496
Closed

cannot watch non-existent files #49

tve opened this issue Oct 20, 2014 · 9 comments · Fixed by #496

Comments

@tve
Copy link

tve commented Oct 20, 2014

Maybe I'm mis-understanding the semantics of fsnotify, but I'm surprised by the fact that I can't watch non-existent files. E.g., I can't watch a filename and then get a CREATE event when it's created. Or, if I watch a file and it's replaced via a REMOVE then I can no longer track it. This means that to reliably track changes to a file I must watch the file's directory!?

Example:

package main

import (
        "time"

        "gopkg.in/fsnotify.v1"
)

func main() {
        w, _ := fsnotify.NewWatcher()
        w.Add("foo")
        go func() {
                for ev := range w.Events {
                        println("Event: ", ev.String())
                }
        }()
        go func() {
                for err := range w.Errors {
                        println("Error: ", err)
                }
        }()
        time.Sleep(60 * time.Second)

}

Test:

$ go version
go version go1.3 linux/amd64
$ rm foo
$ go run notify.go &
[1] 6990
$ echo hello >foo
# I was expecting a CREATE event at this point...
$ kill %1
[1]   Exit 2                  go run notify.go

$ go run notify.go &
[2] 7004
$ echo hello >foo
Event:  "foo": WRITE
Event:  "foo": WRITE
# This time I got the event because foo already existed, but why do I get two write events?
$ rm foo
$ Event:  "foo": REMOVE
$ echo hello >foo
# I was expecting a CREATE event at this point...
$ kill %2
@nathany
Copy link
Contributor

nathany commented Oct 20, 2014

It depends a lot on which OS you're using, but you probably want to watch the directory that you will be creating a file in.

@freaker2k7
Copy link

-1

No I'm not, because the folder doesn't exist as well.

@sorenisanerd
Copy link

@freaker2k7 Then keep going up the directory tree until something exists.

@freaker2k7
Copy link

That misses the whole point.

The whole beauty is to be able to watch the folder once it's created and on.

@sorenisanerd
Copy link

Ok. I'm just telling you what will work.

@sorenisanerd
Copy link

What I've done in a few situations is to watch a directory and whenever it changes, I walk the whole tree and add any missing directories to my watch list. Easy peasy.

@freaker2k7
Copy link

That's an awful solution when you have a big folder like /etc, /dev or any other directory with many files.
Your solution just abuses the IO.

@sorenisanerd
Copy link

Well, that's how inotify works.

Whether you do this from your application or if this functionality is added to fsnotify, it's going to "abuse the IO" just the same.

@arp242
Copy link
Member

arp242 commented Jul 31, 2022

Pretty much all file notification backends work by getting a file descriptor or handle to the path you want to watch; if this path doesn't exist, then we can't get a file descriptor.

The general strategy for this will be to wait until the path exists:

for {
    if fileExists(path) {
        watcher.Add(path)
        break
    }
    time.Sleep(100*time.Millisecond)
}

I'm not convinced that this is something that needs to be added to this library; it's quite a bit of plumbing to do this well which makes this more complex, and this is the only issue raised about this that I can find in ten years, so there doesn't seem to be that much demand for it.

Should probably document though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants