Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Mac: fs.watch triggered twice on fs.writeFile #2054

Closed
TrevorBurnham opened this issue Nov 8, 2011 · 7 comments
Closed

Mac: fs.watch triggered twice on fs.writeFile #2054

TrevorBurnham opened this issue Nov 8, 2011 · 7 comments

Comments

@TrevorBurnham
Copy link

Related: #1970. Tested under Mac OS 10.7.2. Here's the code:

var fs = require('fs');
var prevStats = null;

fs.watch('file', function() {
  fs.stat('file', function(err, stats) {
    if (prevStats && (stats.size === prevStats.size) && (prevStats.mtime.getTime() === stats.mtime.getTime())) return;
    prevStats = stats;
    console.log(stats.size);
  });
});
fs.writeFile('file', 'Arbitrary string');

The output I get is usually

0
16

though sometimes it's just the expected

16
@ghost
Copy link

ghost commented Nov 9, 2011

Same on Ubuntu (running 11.04)

@ghost
Copy link

ghost commented Nov 9, 2011

BTW, when I run the above code by Trevor, it outputs:

node: src/unix/core.c:149: uv_close: Assertion `0' failed.
Aborted

@TrevorBurnham
Copy link
Author

@khoomeister That's what happens when you try to watch a file that doesn't already exist. And yes, it would be nice if Node provided an error to that effect.

On Nov 9, 2011, at 3:21 AM, khoomeisterreply@reply.github.com wrote:

BTW, when I run the above code, it shows:

node: src/unix/core.c:149: uv_close: Assertion `0' failed.
Aborted


Reply to this email directly or view it on GitHub:
#2054 (comment)

@ghost
Copy link

ghost commented Nov 9, 2011

Oh - thanks for that.

@ghost ghost assigned bnoordhuis Nov 9, 2011
@nikhilm
Copy link

nikhilm commented Sep 19, 2012

The double notification is because a write to a file triggers two kqueue events NOTE_EXTEND and NOTE_WRITE. These can either be bundled in the same event if the check interval is fast enough, or be sent as separate events. In which case, should this be considered a libuv bug? Because a pure kqueue program behaves in the same way.

The second part about throwing an error on non-existent file has been fixed, you now get an ENOENT on release builds

@loyd
Copy link

loyd commented Oct 23, 2012

How long to wait for correction?
Forced to use the delay.

var blocked = {};

// decorator
function wch(fn) {
  return function(event, path) {
    if(path in blocked) return;
    blocked[path] = true;
    setTimeout(function() { delete blocked[path] }, 25);
    fn(event, path);
  }
}

fs.watch(pathdir, wch(function(event, filename) { ... }));

There are more reliable solutions?

@bnoordhuis
Copy link
Member

Closing. As @nikhilm pointed out, it's not really a bug - it's legal for the kernel to coalesce some events and that's exactly what it does.

@loyd The master branch uses fsevents now for watching directories (not files), maybe that'll work better for you.

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

No branches or pull requests

4 participants