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

Recursive events not triggering from root drive on Windows #148

Open
lsegal opened this issue Mar 11, 2018 · 7 comments
Open

Recursive events not triggering from root drive on Windows #148

lsegal opened this issue Mar 11, 2018 · 7 comments
Labels

Comments

@lsegal
Copy link

lsegal commented Mar 11, 2018

If notify.Watch() is called on the root of a drive on Windows using recursive syntax ("..."), events don't seem to trigger.

Minimal repro using a slightly modified version of the Recursive example in docs:

package main

import (
	"log"

	"github.com/rjeczalik/notify"
)

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

	// Handles recursive file modifications inside user dir just fine:
	// err := notify.Watch(os.Getenv("HOMEPATH")+"...", c, notify.All)

	// fails to capture any recursive events
	err := notify.Watch("C:\\...", c, notify.All)

	if err != nil {
		log.Fatal(err)
	}
	defer notify.Stop(c)

	for {
		ei := <-c
		log.Println("Got event:", ei)
	}
}

Trying to watch for events on C:\ doesn't seem to fire when changes are made inside my user dir. Only changes directly in C:\ trigger. On the other hand, if I use the commented out HOMEPATH version, I see changes in subdirectories (like Chrome touching files in AppData, for example).

If this is intended behavior or some known limitation, are there any workarounds for this?

@lsegal
Copy link
Author

lsegal commented Mar 12, 2018

After digging through some internals, I figured it out.

Pro tip: to watch a full drive, the watch path should be in the form C:..., not C:\.... The \ breaks everything. This might be something worth documenting (or explicitly handling do people can't make this mistake).

@rjeczalik
Copy link
Owner

@lsegal Actually it is a bug in this case. However unusual, to watch the whole drive, it should be working. Thanks for debugging this!

@rjeczalik rjeczalik added the bug label Mar 12, 2018
@ppknap
Copy link
Collaborator

ppknap commented Mar 12, 2018

@lsegal Thanks for reporting this. It definitely looks like a bug since there shouldn't be any difference between watching root directory and any other path.

@ppknap ppknap self-assigned this Mar 12, 2018
@lsegal
Copy link
Author

lsegal commented Jun 7, 2018

Not sure what happened on this since my last tests but it seems like the C:... trick no longer works. Wondering if there's been any movement on this?

I should point out that it may seem odd to watch a full drive like C:\, but consider that this is also broken for secondary drives like small removable ones that get mounted to D:, E:, etc., where watching a full drive would be much more sensible.

@lsegal
Copy link
Author

lsegal commented Jun 7, 2018

FYI I was doing some more digging on this and found debug logging, which is great. I've managed to reproduce a potential issue with the following minimal case:

package main

import (
	"fmt"

	"github.com/rjeczalik/notify"
)

func main() {
	ch := make(chan notify.EventInfo)
	err := notify.Watch(`D:...`, ch, notify.All)
	if err != nil {
		panic(err)
	}
	for {
		fmt.Println(<-ch)
	}
}

If I then go run -tags debug main.go and create a new folder or file in the root of D:\ followed by a subdirectory of D:\, I see the following debug info with no printed event on the latter dir creation:

[D] dispatching notify.Create on "D:\\New folder"

notify.Create: "D:\New folder"
[D] dispatching notify.Remove on "D:\\New folder"

notify.Remove: "D:\New folder"
[D] dispatching notify.Create on "D:\\Code\\New folder"

[D] dispatch did not reach leaf:Node D:\Code: file does not exist

Digging further, it seems like the error is returned from node.go#L222 because r.nd.Child does not contain child directories for the root D: volume. Printing the contents of that map shows:

map[D::{D: map[] map[:{D:\ map[0xc042014300:notify.Write|notify.Rename|recursive|notify.Create|notify.Remove <nil>:notify.Create|notify.Remove|notify.Write|notify.Rename|recursive] map[]}]}]

I'd expect to see other root folders in that list.

@lsegal
Copy link
Author

lsegal commented Jun 11, 2018

Another update: I've also noticed that this same behavioral bug is present on macOS, so it seems like related to the recursive watcher not correctly initializing r.nd.Child map when given a root path.

@ppknap
Copy link
Collaborator

ppknap commented Jun 12, 2018

Thank you @lsegal for this thoughtful investigation! Indeed, this isn't a problem with Windows watcher itself.

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

No branches or pull requests

3 participants