fsevents_to_vm icon indicating copy to clipboard operation
fsevents_to_vm copied to clipboard

FYI: issue with Vim and fsevents_to_vm on file events

Open gkop opened this issue 9 years ago • 7 comments
trafficstars

Steps to replicate

  1. On host, open foo.js in Vim [0] with an empty .vimrc
  2. On vm, run inotifywait foo.js
  3. Edit foo.js and save in Vim

Expected behavior inotifywait reports the file has changed

Observed behavior inotifywait does not report anything

Fix for Vim is to add set backupcopy=yes to .vimrc .

Note that inotifywait on the directory containing foo.js does report an event.

Could this behavior be due to the limitation to fsevents_to_vm that Multiple events for the same file within the same 1/100th of a second may cause events to be missed.?

[0] I'm using the vim binary provided by MacVim, in my terminal.

gkop avatar May 13 '16 23:05 gkop

This is a consequence of how fsevents_to_vm works -- it doesn't actually modify the file, just the file's metadata attributes (specifically the mtime). This shows up as an inotify ATTRIB event on the directory. This hasn't been a problem in practice because all the use cases we've cared about (guard, webpack, etc) react to these events. Are you seeing a specific problem, or were you just investigating how it worked?

codekitchen avatar May 16 '16 16:05 codekitchen

Yes, I was bit by this when passing individual files to watchify.

gkop avatar May 16 '16 16:05 gkop

In theory we could use the same de-duping logic that we have for mtime changes, but actually open up the file. I wonder if a zero-length write would trigger an event. It'd take some testing to see what we can get away with.

codekitchen avatar May 16 '16 18:05 codekitchen

I've had the same issue with live reloading in Phoenix. I've tracked the issue down to this line https://github.com/synrc/fs/blob/master/src/sys/inotifywait.erl#L11

It looks like they don't watch for ATTRIB at all.

szlend avatar May 24 '16 21:05 szlend

Good info thanks. They watch for close_write, which according to http://linux.die.net/man/1/inotifywait means "A watched file or a file within a watched directory was closed, after being opened in writeable mode. This does not necessarily imply the file was written to."

So in theory, we could open the file for writing, then immediately close it without writing anything, and it should work with Phoenix and probably most others who don't watch for attrib changes.

It'll be a while before I have time to work on this, though.

codekitchen avatar May 24 '16 22:05 codekitchen

Yeah, I just tested it with open('test', 'a', &:flush) and that triggered it for me.

szlend avatar May 24 '16 22:05 szlend

I've got a WIP branch that simulates WRITE_CLOSE events, which appears to be enough to fix this issue.

However, it doesn't look like that's good enough for the inotify.go library (and thus CompileDaemon), which doesn't watch for WRITE_CLOSE and requires an actual MODIFY event. The only way to get a modify event is to actually modify the file in the docker VM, which is of course a lot more problematic... I'll have to think about it for a while. I'm not sure what the solution could be yet.

codekitchen avatar Jan 04 '18 20:01 codekitchen