yuanchuan / node-watch

A wrapper and enhancements for fs.watch
https://npm.im/node-watch
MIT License
340 stars 44 forks source link

node-watch is not working recursive in Ubuntu under WSL #111

Open intervalia opened 3 years ago

intervalia commented 3 years ago

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.

yuanchuan commented 3 years ago

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)
intervalia commented 3 years ago

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.

yuanchuan commented 3 years ago

Possible related:

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

jasondalycan commented 2 years ago

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.

intervalia commented 11 months ago

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.