wc-duck / fswatcher

cross-platform filewatcher library for c/c++
Other
99 stars 8 forks source link

Save file once event triggers twice #5

Open tuket opened 3 years ago

tuket commented 3 years ago

Hi,

I have noticed that, at least in Windows, when I save a file, the event triggers twice. I'm using fswatcher_poll. This could be a bug in the Windows API though:

wc-duck commented 3 years ago

Sorry for the late reply, I'll blame family life ;) I would not say that this is an issue neither with the windows api or fswatcher. The windows API is just reporting the actual events on a filesystem level and fswatcher is just reporting these events to you. From what I can tell it is due to how specific programs create and/or modify files. So fswatcher will keep reporting the events that it get from the OS as fswatcher can't really decide what events is of interest for its users.

However I can see that this is a problem for some users, so maybe we can do something to help out! From my point of view, users might want to solve this in different ways depending on what they want to do.

1) they could collect all change-events to the same file for each call to poll and only report it once. This would not require any tracking data between calls to fswatcher_poll BUT might in some edge-cases not work as the OS-level events might end up in different "polls". I would guess that it is rare and might be fine for most usecases.

2) an app might keep a state and only fire of change-events after a timeout, this might be fine for some applications but not for others.

So what I see is that fswatcher could help out by providing a field in its events, that could be used to track specific files. (inode on linux, fileid on windows?). And MAYBE fswatcher could provide an fswatcher_poll that collects all modify-create calls in one poll to one event, or at least some doc/example on how to do it? And finally doc/example on how to do the timeout in a simple way.

Does that sound like a valid way of doing it to you?

tuket commented 3 years ago

Hi, thanks for your reply. I did try different text editors for saving the file (VS Code, Notepad++, and notepad) and all of them where triggering twice. That makes me think it's not something that programs are doing. I would like to try to do a simple C program that just does fopen, fwrite and fclose and see if also triggers twice (maybe fwrite triggers once and fclose triggers the second time). I will try that later.

I think option 1 is very reasonable to do, and should be enough for most use cases too.

Option 2 adds a bit more complexity to the API, so I'm not sure if it's better to leave it for users to implement it if they need it.

wc-duck commented 3 years ago

So I did some quick checks and I'm not sure I can get the file-id:s on either windows or linux from the events provided in the callbacks from the OS:es. I would have to fetch them via stat()-calls ( or similar ) and that will not work if there are multiple events such as edit -> move -> edit -> move. I'll keep tinkering to see if I can figure out something better.

deadash commented 2 years ago

There seems to be no good way to solve this problem

Most people use the anti-shake function call, or view the last modification time of the file.

You can use procmon to check the occurrence of the event, it should also be twice.

https://stackoverflow.com/questions/1764809/filesystemwatcher-changed-event-is-raised-twice https://stackoverflow.com/questions/14036449/c-winapi-readdirectorychangesw-receiving-double-notifications