mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-21 00:59:03 +01:00
Add logging for TS extension file watcher creation (#185813)
Add logging for extension file watcher creation
This commit is contained in:
@@ -78,7 +78,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<Api> {
|
||||
logDirectoryProvider: noopLogDirectoryProvider,
|
||||
cancellerFactory: noopRequestCancellerFactory,
|
||||
versionProvider,
|
||||
processFactory: new WorkerServerProcessFactory(context.extensionUri),
|
||||
processFactory: new WorkerServerProcessFactory(context.extensionUri, logger),
|
||||
activeJsTsEditorTracker,
|
||||
serviceConfigurationProvider: new BrowserServiceConfigurationProvider(),
|
||||
experimentTelemetryReporter,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Utils } from 'vscode-uri';
|
||||
import { Schemes } from '../configuration/schemes';
|
||||
import { Logger } from '../logging/logger';
|
||||
import { disposeAll, IDisposable } from '../utils/dispose';
|
||||
import { ResourceMap } from '../utils/resourceMap';
|
||||
|
||||
@@ -18,19 +19,27 @@ type DirWatcherEntry = {
|
||||
export class FileWatcherManager {
|
||||
|
||||
private readonly _fileWatchers = new Map<number, {
|
||||
readonly uri: vscode.Uri;
|
||||
readonly watcher: vscode.FileSystemWatcher;
|
||||
readonly dirWatchers: DirWatcherEntry[];
|
||||
}>();
|
||||
|
||||
private readonly _dirWatchers = new ResourceMap<{
|
||||
readonly uri: vscode.Uri;
|
||||
readonly watcher: vscode.FileSystemWatcher;
|
||||
refCount: number;
|
||||
}>(uri => uri.toString(), { onCaseInsensitiveFileSystem: false });
|
||||
|
||||
constructor(
|
||||
private readonly logger: Logger,
|
||||
) { }
|
||||
|
||||
create(id: number, uri: vscode.Uri, watchParentDirs: boolean, isRecursive: boolean, listeners: { create?: (uri: vscode.Uri) => void; change?: (uri: vscode.Uri) => void; delete?: (uri: vscode.Uri) => void }): void {
|
||||
this.logger.trace(`Creating file watcher for ${uri.toString()}`);
|
||||
|
||||
const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(uri, isRecursive ? '**' : '*'), !listeners.create, !listeners.change, !listeners.delete);
|
||||
const parentDirWatchers: DirWatcherEntry[] = [];
|
||||
this._fileWatchers.set(id, { watcher, dirWatchers: parentDirWatchers });
|
||||
this._fileWatchers.set(id, { uri, watcher, dirWatchers: parentDirWatchers });
|
||||
|
||||
if (listeners.create) { watcher.onDidCreate(listeners.create); }
|
||||
if (listeners.change) { watcher.onDidChange(listeners.change); }
|
||||
@@ -43,9 +52,10 @@ export class FileWatcherManager {
|
||||
|
||||
let parentDirWatcher = this._dirWatchers.get(dirUri);
|
||||
if (!parentDirWatcher) {
|
||||
this.logger.trace(`Creating parent dir watcher for ${dirUri.toString()}`);
|
||||
const glob = new vscode.RelativePattern(Utils.dirname(dirUri), Utils.basename(dirUri));
|
||||
const parentWatcher = vscode.workspace.createFileSystemWatcher(glob, !listeners.create, true, !listeners.delete);
|
||||
parentDirWatcher = { refCount: 0, watcher: parentWatcher };
|
||||
parentDirWatcher = { uri: dirUri, refCount: 0, watcher: parentWatcher };
|
||||
this._dirWatchers.set(dirUri, parentDirWatcher);
|
||||
}
|
||||
parentDirWatcher.refCount++;
|
||||
@@ -75,15 +85,19 @@ export class FileWatcherManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete(id: number): void {
|
||||
const entry = this._fileWatchers.get(id);
|
||||
if (entry) {
|
||||
this.logger.trace(`Deleting file watcher for ${entry.uri}`);
|
||||
|
||||
for (const dirWatcher of entry.dirWatchers) {
|
||||
disposeAll(dirWatcher.listeners);
|
||||
|
||||
const dirWatcherEntry = this._dirWatchers.get(dirWatcher.uri);
|
||||
if (dirWatcherEntry) {
|
||||
if (--dirWatcherEntry.refCount <= 0) {
|
||||
this.logger.trace(`Deleting parent dir ${dirWatcherEntry.uri}`);
|
||||
dirWatcherEntry.watcher.dispose();
|
||||
this._dirWatchers.delete(dirWatcher.uri);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ServiceConnection } from '@vscode/sync-api-common/browser';
|
||||
import { ApiService, Requests } from '@vscode/sync-api-service';
|
||||
import * as vscode from 'vscode';
|
||||
import { TypeScriptServiceConfiguration } from '../configuration/configuration';
|
||||
import { Logger } from '../logging/logger';
|
||||
import { FileWatcherManager } from './fileWatchingManager';
|
||||
import type * as Proto from './protocol/protocol';
|
||||
import { TsServerLog, TsServerProcess, TsServerProcessFactory, TsServerProcessKind } from './server';
|
||||
@@ -30,6 +31,7 @@ type BrowserWatchEvent = {
|
||||
export class WorkerServerProcessFactory implements TsServerProcessFactory {
|
||||
constructor(
|
||||
private readonly _extensionUri: vscode.Uri,
|
||||
private readonly _logger: Logger,
|
||||
) { }
|
||||
|
||||
public fork(
|
||||
@@ -47,7 +49,7 @@ export class WorkerServerProcessFactory implements TsServerProcessFactory {
|
||||
// Explicitly give TS Server its path so it can
|
||||
// load local resources
|
||||
'--executingFilePath', tsServerPath,
|
||||
], tsServerLog);
|
||||
], tsServerLog, this._logger);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +62,7 @@ class WorkerServerProcess implements TsServerProcess {
|
||||
private readonly _onDataHandlers = new Set<(data: Proto.Response) => void>();
|
||||
private readonly _onErrorHandlers = new Set<(err: Error) => void>();
|
||||
private readonly _onExitHandlers = new Set<(code: number | null, signal: string | null) => void>();
|
||||
private readonly watches = new FileWatcherManager();
|
||||
private readonly _watches: FileWatcherManager;
|
||||
|
||||
private readonly worker: Worker;
|
||||
|
||||
@@ -77,9 +79,12 @@ class WorkerServerProcess implements TsServerProcess {
|
||||
extensionUri: vscode.Uri,
|
||||
args: readonly string[],
|
||||
private readonly tsServerLog: TsServerLog | undefined,
|
||||
logger: Logger,
|
||||
) {
|
||||
this.worker = new Worker(tsServerPath, { name: `TS ${kind} server #${this.id}` });
|
||||
|
||||
this._watches = new FileWatcherManager(logger);
|
||||
|
||||
const tsserverChannel = new MessageChannel();
|
||||
const watcherChannel = new MessageChannel();
|
||||
const syncChannel = new MessageChannel();
|
||||
@@ -100,12 +105,12 @@ class WorkerServerProcess implements TsServerProcess {
|
||||
this.watcher.onmessage = (event: MessageEvent<BrowserWatchEvent>) => {
|
||||
switch (event.data.type) {
|
||||
case 'dispose': {
|
||||
this.watches.delete(event.data.id);
|
||||
this._watches.delete(event.data.id);
|
||||
break;
|
||||
}
|
||||
case 'watchDirectory':
|
||||
case 'watchFile': {
|
||||
this.watches.create(event.data.id, vscode.Uri.from(event.data.uri), /*watchParentDirs*/ true, !!event.data.recursive, {
|
||||
this._watches.create(event.data.id, vscode.Uri.from(event.data.uri), /*watchParentDirs*/ true, !!event.data.recursive, {
|
||||
change: uri => this.watcher.postMessage({ type: 'watch', event: 'change', uri }),
|
||||
create: uri => this.watcher.postMessage({ type: 'watch', event: 'create', uri }),
|
||||
delete: uri => this.watcher.postMessage({ type: 'watch', event: 'delete', uri }),
|
||||
|
||||
Reference in New Issue
Block a user