Search code examples
node.jsfilesublimetext3onchangeis-empty

chokidar: onchange event for a file is possibly triggered to fast


We are watching for file changes using chokidar with nodejs on an Ubuntu server. It works pretty fine, but sometimes I think we have a problem with the way a file is saved when changed: in chokidar the "onchange" event is triggered, but when we read the file in the callback, it is empty or (rarely) not written completely. We don’t know if it is a problem caused by the text editor writing the file, the operating system on the client computer, the OS or filesystem (ext4) on the server or if it is some kind of bug in chokidar.

This empty file problem is now happening almost every time by file changes made from one computer (mac, latest osx version) where sublime 3 is used. In sublime we tried the setting “atomic_save” (creates a temp files and then overwrites the original file), but it did not solve our problem:

  1. With atomic_save set to “false” the file seems to be always empty in the onchange event and
  2. With atomic_save “true” it is sometimes empty and sometimes partly written.

We had this problem before with phpstorm, but after switching to ‘use “safe write” (save changes to a temporary file first)’ - so the same setting as atomic_save in sublime, that’s also why we tried atomic_save in sublime -, the onchange event was triggered correctly after the complete was written.

So our question is, is there a way to have the “onchange” triggered when the file is completely written somehow (in chokidar, in an OS, in sublime)? Or do we have to check the file size in the “onchange” event until hasn’t changed for some time (not so nice)? Or does our problem maybe occur because of something else?

We would appreciate any hints! Thanks in advance!


Solution

  • Looking through the performance section of the chokidar README, I found the following:

    awaitWriteFinish (default: false). By default, the add event will fire when a file first appear on disk, before the entire file has been written. Furthermore, in some cases some change events will be emitted while the file is being written. In some cases, especially when watching for large files there will be a need to wait for the write operation to finish before responding to a file creation or modification. Setting awaitWriteFinish to true (or a truthy value) will poll file size, holding its add and change events until the size does not change for a configurable amount of time. The appropriate duration setting is heavily dependent on the OS and hardware. For accurate detection this parameter should be relatively high, making file watching much less responsive. Use with caution.

    • options.awaitWriteFinish can be set to an object in order to adjust timing params:
      • awaitWriteFinish.stabilityThreshold (default: 2000). Amount of time in milliseconds for a file size to remain constant before emitting its event.
      • awaitWriteFinish.pollInterval (default: 100). File size polling interval.

    This looks like it could solve your problem, assuming that more than a few seconds elapse between file saves.