Skip to content

Commit 70f1f8d

Browse files
benjamingrtargos
authored andcommitted
fs: add AbortSignal support to watch
PR-URL: nodejs#37190 Refs: nodejs#37179 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Antoine du Hamel <[email protected]> Reviewed-By: Darshan Sen <[email protected]>
1 parent 5e69c69 commit 70f1f8d

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

doc/api/fs.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,6 +4046,9 @@ this API: [`fs.utimes()`][].
40464046
<!-- YAML
40474047
added: v0.5.10
40484048
changes:
4049+
- version: REPLACEME
4050+
pr-url: https://github.com/nodejs/node/pull/37190
4051+
description: Added support for closing the watcher with an AbortSignal.
40494052
- version: v7.6.0
40504053
pr-url: https://github.com/nodejs/node/pull/10739
40514054
description: The `filename` parameter can be a WHATWG `URL` object using
@@ -4065,6 +4068,7 @@ changes:
40654068
`false`.
40664069
* `encoding` {string} Specifies the character encoding to be used for the
40674070
filename passed to the listener. **Default:** `'utf8'`.
4071+
* `signal` {AbortSignal} allows closing the watcher with an AbortSignal.
40684072
* `listener` {Function|undefined} **Default:** `undefined`
40694073
* `eventType` {string}
40704074
* `filename` {string|Buffer}
@@ -4087,6 +4091,9 @@ The listener callback is attached to the `'change'` event fired by
40874091
[`fs.FSWatcher`][], but it is not the same thing as the `'change'` value of
40884092
`eventType`.
40894093

4094+
If a `signal` is passed, aborting the corresponding AbortController will close
4095+
the returned [`fs.FSWatcher`][].
4096+
40904097
### Caveats
40914098

40924099
<!--type=misc-->

lib/fs.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,17 @@ function watch(filename, options, listener) {
15511551
if (listener) {
15521552
watcher.addListener('change', listener);
15531553
}
1554+
if (options.signal) {
1555+
if (options.signal.aborted) {
1556+
process.nextTick(() => watcher.close());
1557+
} else {
1558+
const listener = () => watcher.close();
1559+
options.signal.addEventListener('abort', listener);
1560+
watcher.once('close', () => {
1561+
options.signal.removeEventListener('abort', listener);
1562+
});
1563+
}
1564+
}
15541565

15551566
return watcher;
15561567
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Flags: --expose-internals --experimental-abortcontroller
2+
'use strict';
3+
4+
// Verify that AbortSignal integration works for fs.watch
5+
6+
const common = require('../common');
7+
8+
if (common.isIBMi)
9+
common.skip('IBMi does not support `fs.watch()`');
10+
11+
const fs = require('fs');
12+
const fixtures = require('../common/fixtures');
13+
14+
15+
{
16+
// Signal aborted after creating the watcher
17+
const file = fixtures.path('empty.js');
18+
const ac = new AbortController();
19+
const { signal } = ac;
20+
const watcher = fs.watch(file, { signal });
21+
watcher.once('close', common.mustCall());
22+
setImmediate(() => ac.abort());
23+
}
24+
{
25+
// Signal aborted before creating the watcher
26+
const file = fixtures.path('empty.js');
27+
const ac = new AbortController();
28+
const { signal } = ac;
29+
ac.abort();
30+
const watcher = fs.watch(file, { signal });
31+
watcher.once('close', common.mustCall());
32+
}

0 commit comments

Comments
 (0)