Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

fs.watch detecting two change events on each write #2126

Closed
TrevorBurnham opened this Issue · 13 comments
@TrevorBurnham

It seems that fs.watch detects every write to a file as two separate changes: one immediate, and one delayed by anywhere from 400ms to 4 seconds. I've run this test case against Node 0.6.1 under the latest OS X:

var fs = require('fs');
var startDate = new Date();
var fswatcher = fs.watch('foo.txt', function(event) {
  console.log(event, new Date() - startDate);
});
fs.writeFile('foo.txt', 'foo bar baz', function(){
  console.log('Write complete');
});

I consistently see two change events, e.g.

change 33
Write complete
change 2259
@wvl

Confirmed, on ubuntu, it consistently resembles:

change 1
change 10
Write complete

On osx, I see results similar to @TrevorBurnham:

change 2
Write complete
change 443
@TrevorBurnham

It's worth noting that the mtime only changes after the initial change. So in the CoffeeScript compilation utility, we've been doing an fs.stat after each change to prevent every change from causing two recompilations.

Also worth noting that this behavior is not caused by writeFile wiping the file away before writing to it (though I'm sometimes seeing a third change event from that, where fs.statSync('foo.txt').size is 0). If I replace the writeFile line with

require('child_process').exec('touch foo.txt');

I see the same "echo" change event.

@wvl Could you try adding

console.log('size', fs.statSync('foo.txt').size);

to the end of the fs.watch callback under Ubuntu? And see if there are two change events from spawning touch? Since the fs.writeFile callback is called after the two changes, I'm guessing that you're seeing two change events from the file being erased and then written to, and that the "echo" is specific to OS X.

@wvl

Ah yes, that's what linux is doing. with fs.writeFile:

change foo.txt 1
size 0
change foo.txt 9
size 11
Write complete

with exec('touch foo.txt'), only one event.

However, with exec('echo "Hello" > foo.txt'), two events, same size:

change foo.txt 12
size 6
change foo.txt 18
size 6
@guiomie

I am getting the same issue on windows 7 64bits, but also when I copy a file.

change 1
change 13
Write complete

@hunterloftis

+1, osx lion, node 0.6.15

@MyBoon

+1, fedora 14, node-v0.6.18

@dnemoga

+1, Windows 7 x64, node-0.6.18

@dnemoga

+1, Windows 7 x64, node-0.6.18

@bdryanovski

Same here, Windows 7 x64, node-0.8.0

@piscisaureus

This is expected. The file is first truncated when it is opened, and then data is written. This triggers 2 change events. We cannot and won't do anything to prevent that.

@matthewmueller

Any chance they could be different events? Perhaps open and write.

@bnoordhuis
Owner

Any chance they could be different events? Perhaps open and write.

The OS API doesn't provide that level of detail.

@abpin

We can add more detailed events since both Linux and windows do support that (I don't know about the rest.)

Linux,
http://linux.die.net/man/7/inotify

  • stat

And for Windows :
here
1- http://msdn.microsoft.com/en-us/library/aa365465(v=vs.85).aspx
2- http://msdn.microsoft.com/en-us/library/system.io.notifyfilters.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
3- http://www.codeproject.com/Articles/950/CDirectoryChangeWatcher-ReadDirectoryChangesW-all

If you care about including more detailed events in the core API, I would put time on a patch.
What do you think?

@vojtatranta vojtatranta referenced this issue from a commit in vojtatranta/grunt-suppe
@steida steida Better algorithm for async tasks execution.
Fixes win joyent/node#2126 issue.
435ea56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.