Path: blob/main/src/vs/platform/files/node/watcher/watcher.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Disposable } from '../../../../base/common/lifecycle.js';6import { ILogMessage, isRecursiveWatchRequest, IUniversalWatcher, IUniversalWatchRequest } from '../../common/watcher.js';7import { Emitter, Event } from '../../../../base/common/event.js';8import { ParcelWatcher } from './parcel/parcelWatcher.js';9import { NodeJSWatcher } from './nodejs/nodejsWatcher.js';10import { Promises } from '../../../../base/common/async.js';11import { computeStats } from './watcherStats.js';1213export class UniversalWatcher extends Disposable implements IUniversalWatcher {1415private readonly recursiveWatcher = this._register(new ParcelWatcher());16private readonly nonRecursiveWatcher = this._register(new NodeJSWatcher(this.recursiveWatcher));1718readonly onDidChangeFile = Event.any(this.recursiveWatcher.onDidChangeFile, this.nonRecursiveWatcher.onDidChangeFile);19readonly onDidError = Event.any(this.recursiveWatcher.onDidError, this.nonRecursiveWatcher.onDidError);2021private readonly _onDidLogMessage = this._register(new Emitter<ILogMessage>());22readonly onDidLogMessage = Event.any(this._onDidLogMessage.event, this.recursiveWatcher.onDidLogMessage, this.nonRecursiveWatcher.onDidLogMessage);2324private requests: IUniversalWatchRequest[] = [];25private failedRecursiveRequests = 0;2627constructor() {28super();2930this._register(this.recursiveWatcher.onDidError(e => {31if (e.request) {32this.failedRecursiveRequests++;33}34}));35}3637async watch(requests: IUniversalWatchRequest[]): Promise<void> {38this.requests = requests;39this.failedRecursiveRequests = 0;4041// Watch recursively first to give recursive watchers a chance42// to step in for non-recursive watch requests, thus reducing43// watcher duplication.4445let error: Error | undefined;46try {47await this.recursiveWatcher.watch(requests.filter(request => isRecursiveWatchRequest(request)));48} catch (e) {49error = e;50}5152try {53await this.nonRecursiveWatcher.watch(requests.filter(request => !isRecursiveWatchRequest(request)));54} catch (e) {55if (!error) {56error = e;57}58}5960if (error) {61throw error;62}63}6465async setVerboseLogging(enabled: boolean): Promise<void> {6667// Log stats68if (enabled && this.requests.length > 0) {69this._onDidLogMessage.fire({ type: 'trace', message: computeStats(this.requests, this.failedRecursiveRequests, this.recursiveWatcher, this.nonRecursiveWatcher) });70}7172// Forward to watchers73await Promises.settled([74this.recursiveWatcher.setVerboseLogging(enabled),75this.nonRecursiveWatcher.setVerboseLogging(enabled)76]);77}7879async stop(): Promise<void> {80await Promises.settled([81this.recursiveWatcher.stop(),82this.nonRecursiveWatcher.stop()83]);84}85}868788