node-watch icon indicating copy to clipboard operation
node-watch copied to clipboard

node-watch is not working recursive in Ubuntu under WSL

Open intervalia opened this issue 4 years ago • 5 comments

WSL allows a user to run versions of Linux under windows.

When running Ubuntu 20.04.2 LTS in WSL I can not seem to get node-watch to do a recursive watch. I am using node-watch v0.7.1

My code:

    watch(folder, {recursive: true}, (eventType, fname) => {

I have walked through the watch code and here is what I have found:

  1. You correctly identify that Ubuntu in WSL does not natively support recursive.
  2. Inside of Watcher.prototype.watchDirectory you walk the entire tree and call do the following with every folder
    var watcher = fs.watch(dir, opts);

    self.add(watcher, {
      type: 'dir',
      fpath: dir,
      options: options
    });

If I change something in the root folder then I get my callback called. But I do not get the callback called for any of the sub folders. I am trying to watch this folder: /mnt/d/Documents/Projects/omega/src and all subs.

I added the following code

  console.log(`wacthing the folder ${info.fpath}`);

Into your watch.js just before you call watcher.on('change', internalOnChange); so I can output the folder being watched and I get this list:

wacthing the folder /mnt/d/Documents/Projects/omega/src/api
wacthing the folder /mnt/d/Documents/Projects/omega/src/lib
wacthing the folder /mnt/d/Documents/Projects/omega/src/routes
wacthing the folder /mnt/d/Documents/Projects/omega/src/sharedViews
wacthing the folder /mnt/d/Documents/Projects/omega/src/static
wacthing the folder /mnt/d/Documents/Projects/omega/src/views
wacthing the folder /mnt/d/Documents/Projects/omega/src/api/account
wacthing the folder /mnt/d/Documents/Projects/omega/src/api/groups
wacthing the folder /mnt/d/Documents/Projects/omega/src/api/users
wacthing the folder /mnt/d/Documents/Projects/omega/src/lib/SessionManager
wacthing the folder /mnt/d/Documents/Projects/omega/src/lib/directoryService
wacthing the folder /mnt/d/Documents/Projects/omega/src/lib/test
wacthing the folder /mnt/d/Documents/Projects/omega/src/sharedViews/system
wacthing the folder /mnt/d/Documents/Projects/omega/src/static/brand
wacthing the folder /mnt/d/Documents/Projects/omega/src/static/css
wacthing the folder /mnt/d/Documents/Projects/omega/src/static/js
wacthing the folder /mnt/d/Documents/Projects/omega/src/views/dialogs
wacthing the folder /mnt/d/Documents/Projects/omega/src/api/groups/(groupName)
wacthing the folder /mnt/d/Documents/Projects/omega/src/api/users/(username)
wacthing the folder /mnt/d/Documents/Projects/omega/src/lib/directoryService/errors
wacthing the folder /mnt/d/Documents/Projects/omega/src/sharedViews/system/node
wacthing the folder /mnt/d/Documents/Projects/omega/src/static/brand/img
wacthing the folder /mnt/d/Documents/Projects/omega/src/static/js/polyfill

That is the full list of my folders.

I just don't get why I am not getting callbacks for sub folders and I do for the root folder.

intervalia avatar Feb 24 '21 22:02 intervalia

Hi @intervalia,

I can't find a WIndows system to test at the moment. My first guess is that the native fs.watch is not working properly under WSL.

Would you do a quick test for watching a sub-directory, say /mnt/d/Documents/Projects/omega/src/api, to see if fs.watch works.

fs.watch('/mnt/d/Documents/Projects/omega/src/api', console.log)

yuanchuan avatar Feb 25 '21 06:02 yuanchuan

Interesting!!

I wrote this code:

const path = require('path');
const fs = require('fs');
const fsp = fs.promises;

async function runForever() {
  if (!fs.existsSync('./temp/one/a')) {
    await fsp.mkdir('./temp/one/a', { recursive: true })
  }

  if (!fs.existsSync('./temp/one/b')) {
    await fsp.mkdir('./temp/one/b', { recursive: true });
  }

  function listener(eventType, filename) {
    console.log(eventType, filename);
  }

  const options = {
    persistent: true,
    recursive: false,
    encoding: 'utf8'
  };
  const watchPath = path.join(__dirname, 'temp');
  console.log({watchPath});
  fs.watch(watchPath, options, listener);

  console.log(`Waiting for changes`);
  return new Promise((resolve, reject) => {
    // Do nothing. This is meant to wait forever
  });
}

runForever().then(() => console.log('finished')).catch(ex => console.error(ex.stack));

And it runs fin in Windows, but does not seem to work on UBUNTU in WLS.

I will try further testing.

intervalia avatar Feb 27 '21 23:02 intervalia

Possible related:

https://github.com/microsoft/WSL/issues/4739

yuanchuan avatar Feb 28 '21 03:02 yuanchuan

I tested this on WSL2 (Debian 11) and watching a Windows directory from within WSL (i.e. /mnt/c/my-dir) returns no results (nothing happens if files are written/changed within /mnt/c/my-dir) but when watching a WSL directory within the Linux filesystem (i.e. /my-linux-dir) it appears to function as expected - without support for recursive as identified above.

jasondalycan avatar Aug 11 '22 19:08 jasondalycan

FYI: I am no longer on the project that had this issue and have no way of validating if this is working or not. I still think it would be a good feature. Others will have to validate if it works.

intervalia avatar Oct 13 '23 14:10 intervalia