Skip to content

Commit

Permalink
fs: add AbortSignal support to watch
Browse files Browse the repository at this point in the history
PR-URL: #37190
Backport-PR-URL: #38386
Refs: #37179
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
  • Loading branch information
benjamingr authored and targos committed Apr 30, 2021
1 parent 81cd06b commit 7aa2e5d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
7 changes: 7 additions & 0 deletions doc/api/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4060,6 +4060,9 @@ this API: [`fs.utimes()`][].
<!-- YAML
added: v0.5.10
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/37190
description: Added support for closing the watcher with an AbortSignal.
- version: v7.6.0
pr-url: https://github.com/nodejs/node/pull/10739
description: The `filename` parameter can be a WHATWG `URL` object using
Expand All @@ -4079,6 +4082,7 @@ changes:
`false`.
* `encoding` {string} Specifies the character encoding to be used for the
filename passed to the listener. **Default:** `'utf8'`.
* `signal` {AbortSignal} allows closing the watcher with an AbortSignal.
* `listener` {Function|undefined} **Default:** `undefined`
* `eventType` {string}
* `filename` {string|Buffer}
Expand All @@ -4101,6 +4105,9 @@ The listener callback is attached to the `'change'` event fired by
[`fs.FSWatcher`][], but it is not the same thing as the `'change'` value of
`eventType`.

If a `signal` is passed, aborting the corresponding AbortController will close
the returned [`fs.FSWatcher`][].

### Caveats

<!--type=misc-->
Expand Down
11 changes: 11 additions & 0 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,17 @@ function watch(filename, options, listener) {
if (listener) {
watcher.addListener('change', listener);
}
if (options.signal) {
if (options.signal.aborted) {
process.nextTick(() => watcher.close());
} else {
const listener = () => watcher.close();
options.signal.addEventListener('abort', listener);
watcher.once('close', () => {
options.signal.removeEventListener('abort', listener);
});
}
}

return watcher;
}
Expand Down
32 changes: 32 additions & 0 deletions test/parallel/test-fs-watch-abort-signal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Flags: --expose-internals --experimental-abortcontroller
'use strict';

// Verify that AbortSignal integration works for fs.watch

const common = require('../common');

if (common.isIBMi)
common.skip('IBMi does not support `fs.watch()`');

const fs = require('fs');
const fixtures = require('../common/fixtures');


{
// Signal aborted after creating the watcher
const file = fixtures.path('empty.js');
const ac = new AbortController();
const { signal } = ac;
const watcher = fs.watch(file, { signal });
watcher.once('close', common.mustCall());
setImmediate(() => ac.abort());
}
{
// Signal aborted before creating the watcher
const file = fixtures.path('empty.js');
const ac = new AbortController();
const { signal } = ac;
ac.abort();
const watcher = fs.watch(file, { signal });
watcher.once('close', common.mustCall());
}

0 comments on commit 7aa2e5d

Please sign in to comment.