mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 17:32:41 +00:00
watcher - fix some things (#207597)
This commit is contained in:
parent
3acfc00951
commit
d1a1dd2784
|
@ -43,6 +43,14 @@ interface IWatchRequest {
|
|||
readonly correlationId?: number;
|
||||
}
|
||||
|
||||
export interface IWatchRequestWithCorrelation extends IWatchRequest {
|
||||
readonly correlationId: number;
|
||||
}
|
||||
|
||||
export function isWatchRequestWithCorrelation(request: IWatchRequest): request is IWatchRequestWithCorrelation {
|
||||
return typeof request.correlationId === 'number';
|
||||
}
|
||||
|
||||
export interface INonRecursiveWatchRequest extends IWatchRequest {
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { watchFile, unwatchFile, Stats } from 'fs';
|
||||
import { Disposable, DisposableMap, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ILogMessage, IUniversalWatchRequest, IWatcher } from 'vs/platform/files/common/watcher';
|
||||
import { ILogMessage, IUniversalWatchRequest, IWatchRequestWithCorrelation, IWatcher, isWatchRequestWithCorrelation } from 'vs/platform/files/common/watcher';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { FileChangeType, IFileChange } from 'vs/platform/files/common/files';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
@ -21,10 +21,12 @@ export abstract class BaseWatcher extends Disposable implements IWatcher {
|
|||
protected readonly _onDidWatchFail = this._register(new Emitter<IUniversalWatchRequest>());
|
||||
private readonly onDidWatchFail = this._onDidWatchFail.event;
|
||||
|
||||
private allWatchRequests = new Set<IUniversalWatchRequest>();
|
||||
private readonly suspendedWatchRequests = this._register(new DisposableMap<IUniversalWatchRequest>());
|
||||
private readonly allNonCorrelatedWatchRequests = new Set<IUniversalWatchRequest>();
|
||||
private readonly allCorrelatedWatchRequests = new Map<number /* correlation ID */, IWatchRequestWithCorrelation>();
|
||||
|
||||
protected readonly suspendedWatchRequestPollingInterval: number | undefined;
|
||||
private readonly suspendedWatchRequests = this._register(new DisposableMap<number /* correlation ID */>());
|
||||
|
||||
protected readonly suspendedWatchRequestPollingInterval: number = 5007; // node.js default
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -46,17 +48,27 @@ export abstract class BaseWatcher extends Disposable implements IWatcher {
|
|||
this.suspendWatchRequest(request);
|
||||
}
|
||||
|
||||
protected isCorrelated(request: IUniversalWatchRequest): boolean {
|
||||
return typeof request.correlationId === 'number';
|
||||
protected isCorrelated(request: IUniversalWatchRequest): request is IWatchRequestWithCorrelation {
|
||||
return isWatchRequestWithCorrelation(request);
|
||||
}
|
||||
|
||||
async watch(requests: IUniversalWatchRequest[]): Promise<void> {
|
||||
this.allWatchRequests = new Set([...requests]);
|
||||
this.allCorrelatedWatchRequests.clear();
|
||||
this.allNonCorrelatedWatchRequests.clear();
|
||||
|
||||
// Remove all suspended watch requests that are no longer watched
|
||||
for (const [request] of this.suspendedWatchRequests) {
|
||||
if (!this.allWatchRequests.has(request)) {
|
||||
this.suspendedWatchRequests.deleteAndDispose(request);
|
||||
// Figure out correlated vs. non-correlated requests
|
||||
for (const request of requests) {
|
||||
if (this.isCorrelated(request)) {
|
||||
this.allCorrelatedWatchRequests.set(request.correlationId, request);
|
||||
} else {
|
||||
this.allNonCorrelatedWatchRequests.add(request);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove all suspended correlated watch requests that are no longer watched
|
||||
for (const [correlationId] of this.suspendedWatchRequests) {
|
||||
if (!this.allCorrelatedWatchRequests.has(correlationId)) {
|
||||
this.suspendedWatchRequests.deleteAndDispose(correlationId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,29 +76,32 @@ export abstract class BaseWatcher extends Disposable implements IWatcher {
|
|||
}
|
||||
|
||||
private updateWatchers(): Promise<void> {
|
||||
return this.doWatch(Array.from(this.allWatchRequests).filter(request => !this.suspendedWatchRequests.has(request)));
|
||||
return this.doWatch([
|
||||
...this.allNonCorrelatedWatchRequests,
|
||||
...Array.from(this.allCorrelatedWatchRequests.values()).filter(request => !this.suspendedWatchRequests.has(request.correlationId))
|
||||
]);
|
||||
}
|
||||
|
||||
private suspendWatchRequest(request: IUniversalWatchRequest): void {
|
||||
if (this.suspendedWatchRequests.has(request)) {
|
||||
private suspendWatchRequest(request: IWatchRequestWithCorrelation): void {
|
||||
if (this.suspendedWatchRequests.has(request.correlationId)) {
|
||||
return; // already suspended
|
||||
}
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
this.suspendedWatchRequests.set(request, disposables);
|
||||
this.suspendedWatchRequests.set(request.correlationId, disposables);
|
||||
|
||||
this.monitorSuspendedWatchRequest(request, disposables);
|
||||
|
||||
this.updateWatchers();
|
||||
}
|
||||
|
||||
private resumeWatchRequest(request: IUniversalWatchRequest): void {
|
||||
this.suspendedWatchRequests.deleteAndDispose(request);
|
||||
private resumeWatchRequest(request: IWatchRequestWithCorrelation): void {
|
||||
this.suspendedWatchRequests.deleteAndDispose(request.correlationId);
|
||||
|
||||
this.updateWatchers();
|
||||
}
|
||||
|
||||
private monitorSuspendedWatchRequest(request: IUniversalWatchRequest, disposables: DisposableStore) {
|
||||
private monitorSuspendedWatchRequest(request: IWatchRequestWithCorrelation, disposables: DisposableStore) {
|
||||
const resource = URI.file(request.path);
|
||||
const that = this;
|
||||
|
||||
|
|
|
@ -136,9 +136,7 @@ export class NodeJSWatcher extends BaseWatcher implements INonRecursiveWatcher {
|
|||
}
|
||||
|
||||
protected warn(message: string): void {
|
||||
if (this.verboseLogging) {
|
||||
this._onDidLogMessage.fire({ type: 'warn', message: this.toMessage(message) });
|
||||
}
|
||||
this._onDidLogMessage.fire({ type: 'warn', message: this.toMessage(message) });
|
||||
}
|
||||
|
||||
private toMessage(message: string): string {
|
||||
|
|
|
@ -81,7 +81,7 @@ export class NodeJSFileWatcherLibrary extends Disposable {
|
|||
if (error.code !== 'ENOENT') {
|
||||
this.error(error);
|
||||
} else {
|
||||
this.trace(error);
|
||||
this.trace(`ignoring a path for watching who's stat info failed to resolve: ${this.request.path} (error: ${error})`);
|
||||
}
|
||||
|
||||
this.onDidWatchFail?.();
|
||||
|
|
Loading…
Reference in a new issue