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

Atomic saves in text editors cause havoc, unable to watch individual files #17

Closed
nathany opened this issue Jun 29, 2014 · 4 comments
Closed

Comments

@nathany
Copy link
Contributor

nathany commented Jun 29, 2014

Reported by @robfig at howeyc/fsnotify#91. See also nathany/looper#14.

When editors use atomic saves they Create a new file and then do a Rename rather than just a straight Write (like when touching a file).

Related issues:

Dealing with text editors may be out of scope of fsnotify itself, but it could at least provide recommendations in the Wiki.

@robfig also reported some other oddities, though those may be specific to kqueue on OS X.

@mstum
Copy link

mstum commented Jun 29, 2014

It seems that there are two major use cases to use a Watcher:

  1. Watch very few individual files, e.g. config files for hot reload
  2. Watch a folder, e.g., a "Queue" folder in which the user copies images/logs to be processed by the app and moved to an output folder

Number 1 suffers from said problem. I don't know specifics of OS implementations wrt efficiency, but it seems that setting up a "Delete" watcher which checks if the file is recreated and automatically sets up a new OS watcher for the new file would do the trick. To my knowledge, Move Operations are atomic in all decent file systems (I know they are in NTFS, I don't know or care if they are in FAT32/exFAT), but I don't know if a move can overwrite or if it's required to delete first and then move/rename. In that case, the watcher could be setup on the directory, equipped with a timer that checks every few ms and is automatically deleted if the file isn't coming back after let's say 1s. That works for small files, but let's say the file is a gigabyte in size, I don't know if that would work (then again, I don't know how often a hot-reload-watcher would be used on a large file)

I feel that a "persistent write timer" is more a high level utility construct: Allow me to specify how long the timer stays alive to re-check for file creation. In fact, I wonder if it's best to have fsnotify be a small layer of abstraction on top of the OS watcher - warts/gotchas and all - and then have a "Utility" for high level stuff. That way, the (what I consider) common use case of hot-reloading a tiny config file that's created within a second of a delete is trivial, but someone who wants something "weird" (like hot reloading gigabyte-sized files that are using copy-on-save) still has low level access.

@clipperhouse
Copy link

We might consider an abstraction over fsnotify proper to specify “desired” behavior.

One case might be to compare before & after on a given file, not unlike source control. Then emit a changed event, defined as the bytes having actually changed. This is more inline with what we expect with change events in JS in a browser, eg.

The CREATE/DELETE cycles that editors like Sublime generate might be mitigated by a throttle/debounce. Though at that point, it’s (logically) close to polling. And there is the possibility of races & inconsistency.

@nathany
Copy link
Contributor Author

nathany commented Oct 16, 2015

TextMate2 (OS X) use the exchangedata system call to perform the saves (not sure what that is). But Hugo users are having problems detecting saves: gohugoio/hugo#1053 (comment)

nathany pushed a commit that referenced this issue Jan 14, 2016
`os.Lstat` does not return `error` when a file/directory exists,
so the code path  to check for newly created files after a REMOVE
on BSD was never executed.

Also, if the watched entry is a file, it has been removed from the watcher, so do a new-file-check for them as well.

This commit fixes issues on TextMate on OS X and others that uses `exchangedata` to do atomic saves.

See #17. closes #111.
@arp242
Copy link
Member

arp242 commented Jul 24, 2022

Closing this as a duplicate of #372, since it's essentially the same problem. That issue is much newer, but also more comprehensive.

@arp242 arp242 closed this as completed Jul 24, 2022
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

No branches or pull requests

4 participants