Is your feature request related to a problem? Please describe.
Currently, when you do fs.watchFile(...)
the process will run forever.
Describe the solution you'd like
A possibility to watcher.unref()
would be great.
Describe alternatives you've considered
const watchFile = (path, callback, onError) => {
let previousTime = null;
const interval = setInterval(async () => {
try {
const {mtimeMs} = await stat(path);
if (previousTime !== null && mtimeMs !== previousTime) {
callback(mtimeMs, previousTime);
}
previousTime = mtimeMs;
} catch (error) {
clearInterval(interval);
// The error part is off the Node.js API
onError(error);
}
}, 1000 * 60).unref();
};
Edit: seems like the code above is completely unnecessary :man_facepalming:
I found fs.unwatchFile(filename[, listener]), or you mean something different?
@juanarbol fs.unwatchFile()
removes the listener entirely, what this issue is asking for is a .unref()
method that keeps the listener in place but stops is from keeping the process alive.
I'm more interested in this part, can you let me try work it ? @addaleax
@rickyes Sure!
Basically, this would require adding .ref()
and .unref()
methods to the StatWatcher
and FSWatcher
classes in lib/internal/fs/watchers.js
. StatWatcher
is for fs.watchFile()
, FSWatcher
is for fs.watch()
.
For the FSWatcher
case, the C++ FSEventWrap
class needs to be fixed up a bit:
AsyncWrap
, but it should inherit from HandleWrap
. This can be fixed by replacing AsyncWrap::GetConstructorTemplate
with HandleWrap::GetConstructorTemplate
.close()
method can also be removed, it鈥檚 no longer necessary.For the StatWatcher
case, this is tricky to get right, because Node.js currently de-duplicates StatWatcher
s. If the same file is watched twice, the same watcher is returned, so calling .unref()
once on the StatWatcher
should not actually unref the handle. You probably need to add some kind of reference count there, or start returning distinct values from .watchFile()
.
@szmarczak I looked at the implementation logic and maybe fs.watchFile(path, { persistent: false }, callback)
will solve your problem. However, we can still add ref
, unref
functions to StatWatcher
and FSWatcher
classes.
Indeed, thanks. I'd still go for .ref()
& .unref()
to be consistent with other Node.js API.
Most helpful comment
@rickyes Sure!
Basically, this would require adding
.ref()
and.unref()
methods to theStatWatcher
andFSWatcher
classes inlib/internal/fs/watchers.js
.StatWatcher
is forfs.watchFile()
,FSWatcher
is forfs.watch()
.For the
FSWatcher
case, the C++FSEventWrap
class needs to be fixed up a bit:AsyncWrap
, but it should inherit fromHandleWrap
. This can be fixed by replacingAsyncWrap::GetConstructorTemplate
withHandleWrap::GetConstructorTemplate
.close()
method can also be removed, it鈥檚 no longer necessary.For the
StatWatcher
case, this is tricky to get right, because Node.js currently de-duplicatesStatWatcher
s. If the same file is watched twice, the same watcher is returned, so calling.unref()
once on theStatWatcher
should not actually unref the handle. You probably need to add some kind of reference count there, or start returning distinct values from.watchFile()
.