Skip to content

Commit a129962

Browse files
MoLowRafaelGSS
authored andcommitted
watch: use debounce instead of throttle
PR-URL: #48926 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
1 parent 0db104a commit a129962

File tree

4 files changed

+18
-16
lines changed

4 files changed

+18
-16
lines changed

lib/internal/main/watch_mode.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ const args = ArrayPrototypeFilter(process.execArgv, (arg, i, arr) =>
4444
arg !== '--watch' && arg !== '--watch-preserve-output');
4545
ArrayPrototypePushApply(args, kCommand);
4646

47-
const watcher = new FilesWatcher({ throttle: 500, mode: kShouldFilterModules ? 'filter' : 'all' });
47+
const watcher = new FilesWatcher({ debounce: 500, mode: kShouldFilterModules ? 'filter' : 'all' });
4848
ArrayPrototypeForEach(kWatchedPaths, (p) => watcher.watchPath(p));
4949

5050
let graceTimer;

lib/internal/test_runner/runner.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ function runTestFile(path, root, inspectPort, filesWatcher, testNamePatterns) {
428428
function watchFiles(testFiles, root, inspectPort, signal, testNamePatterns) {
429429
const runningProcesses = new SafeMap();
430430
const runningSubtests = new SafeMap();
431-
const watcher = new FilesWatcher({ throttle: 500, mode: 'filter', signal });
431+
const watcher = new FilesWatcher({ debounce: 500, mode: 'filter', signal });
432432
const filesWatcher = { __proto__: null, watcher, runningProcesses, runningSubtests };
433433

434434
watcher.on('changed', ({ owners }) => {

lib/internal/watch_mode/files_watcher.js

+11-9
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ const supportsRecursiveWatching = process.platform === 'win32' ||
2424
class FilesWatcher extends EventEmitter {
2525
#watchers = new SafeMap();
2626
#filteredFiles = new SafeSet();
27-
#throttling = new SafeSet();
27+
#debouncing = new SafeSet();
2828
#depencencyOwners = new SafeMap();
2929
#ownerDependencies = new SafeMap();
30-
#throttle;
30+
#debounce;
3131
#mode;
3232
#signal;
3333

34-
constructor({ throttle = 500, mode = 'filter', signal } = kEmptyObject) {
34+
constructor({ debounce = 500, mode = 'filter', signal } = kEmptyObject) {
3535
super();
3636

37-
validateNumber(throttle, 'options.throttle', 0, TIMEOUT_MAX);
37+
validateNumber(debounce, 'options.debounce', 0, TIMEOUT_MAX);
3838
validateOneOf(mode, 'options.mode', ['filter', 'all']);
39-
this.#throttle = throttle;
39+
this.#debounce = debounce;
4040
this.#mode = mode;
4141
this.#signal = signal;
4242

@@ -74,16 +74,18 @@ class FilesWatcher extends EventEmitter {
7474
}
7575

7676
#onChange(trigger) {
77-
if (this.#throttling.has(trigger)) {
77+
if (this.#debouncing.has(trigger)) {
7878
return;
7979
}
8080
if (this.#mode === 'filter' && !this.#filteredFiles.has(trigger)) {
8181
return;
8282
}
83-
this.#throttling.add(trigger);
83+
this.#debouncing.add(trigger);
8484
const owners = this.#depencencyOwners.get(trigger);
85-
this.emit('changed', { owners });
86-
setTimeout(() => this.#throttling.delete(trigger), this.#throttle).unref();
85+
setTimeout(() => {
86+
this.#debouncing.delete(trigger);
87+
this.emit('changed', { owners });
88+
}, this.#debounce).unref();
8789
}
8890

8991
get watchedPaths() {

test/parallel/test-watch-mode-files_watcher.mjs

+5-5
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe('watch mode file watcher', () => {
2626

2727
beforeEach(() => {
2828
changesCount = 0;
29-
watcher = new FilesWatcher({ throttle: 100 });
29+
watcher = new FilesWatcher({ debounce: 100 });
3030
watcher.on('changed', () => changesCount++);
3131
});
3232

@@ -51,7 +51,7 @@ describe('watch mode file watcher', () => {
5151
assert.strictEqual(changesCount, 1);
5252
});
5353

54-
it('should throttle changes', async () => {
54+
it('should debounce changes', async () => {
5555
const file = path.join(tmpdir.path, 'file2');
5656
writeFileSync(file, 'written');
5757
watcher.filterFile(file);
@@ -61,7 +61,7 @@ describe('watch mode file watcher', () => {
6161
writeFileSync(file, '2');
6262
writeFileSync(file, '3');
6363
writeFileSync(file, '4');
64-
await setTimeout(200); // throttle * 2
64+
await setTimeout(200); // debounce * 2
6565
writeFileSync(file, '5');
6666
const changed = once(watcher, 'changed');
6767
writeFileSync(file, 'after');
@@ -86,8 +86,8 @@ describe('watch mode file watcher', () => {
8686
await writeAndWaitForChanges(watcher, file);
8787

8888
writeFileSync(file, '1');
89+
assert.strictEqual(changesCount, 1);
8990

90-
await setTimeout(200); // avoid throttling
9191
watcher.clearFileFilters();
9292
writeFileSync(file, '2');
9393
// Wait for this long to make sure changes are triggered only once
@@ -97,7 +97,7 @@ describe('watch mode file watcher', () => {
9797

9898
it('should watch all files in watched path when in "all" mode',
9999
{ skip: !supportsRecursiveWatching }, async () => {
100-
watcher = new FilesWatcher({ throttle: 100, mode: 'all' });
100+
watcher = new FilesWatcher({ debounce: 100, mode: 'all' });
101101
watcher.on('changed', () => changesCount++);
102102

103103
const file = path.join(tmpdir.path, 'file5');

0 commit comments

Comments
 (0)