未验证 提交 35eb83ec 编写于 作者: M Martin Aeschlimann 提交者: GitHub

Merge pull request #76009 from microsoft/aeschli/pollingForWSL1

File watcher: use polling for wsl1
......@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { mkdir, open, close, read, write, fdatasync } from 'fs';
import * as os from 'os';
import { promisify } from 'util';
import { IDisposable, Disposable, toDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
import { IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError } from 'vs/platform/files/common/files';
......@@ -408,22 +409,30 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
folders: { path: string, excludes: string[] }[],
onChange: (changes: IDiskFileChange[]) => void,
onLogMessage: (msg: ILogMessage) => void,
verboseLogging: boolean
verboseLogging: boolean,
watcherOptions?: { [key: string]: boolean | number | string }
): WindowsWatcherService | UnixWatcherService | NsfwWatcherService
};
// Single Folder Watcher
if (this.recursiveFoldersToWatch.length === 1) {
if (isWindows) {
watcherImpl = WindowsWatcherService;
} else {
watcherImpl = UnixWatcherService;
let watcherOptions = undefined;
if (this.forcePolling()) {
// WSL needs a polling watcher
watcherImpl = UnixWatcherService;
watcherOptions = { usePolling: true };
} else {
// Single Folder Watcher
if (this.recursiveFoldersToWatch.length === 1) {
if (isWindows) {
watcherImpl = WindowsWatcherService;
} else {
watcherImpl = UnixWatcherService;
}
}
}
// Multi Folder Watcher
else {
watcherImpl = NsfwWatcherService;
// Multi Folder Watcher
else {
watcherImpl = NsfwWatcherService;
}
}
// Create and start watching
......@@ -436,7 +445,8 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
}
this.logService[msg.type](msg.message);
},
this.logService.getLevel() === LogLevel.Trace
this.logService.getLevel() === LogLevel.Trace,
watcherOptions
);
if (!this.recursiveWatcherLogLevelListener) {
......@@ -504,6 +514,12 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
return createFileSystemProviderError(error, code);
}
forcePolling(): boolean {
// wsl1 needs polling
return isLinux && /^[\.\-0-9]+-Microsoft/.test(os.release());
}
//#endregion
dispose(): void {
......
......@@ -23,10 +23,6 @@ interface IWatcher {
stop(): any;
}
export interface IChockidarWatcherOptions {
pollingInterval?: number;
}
interface ExtendedWatcherRequest extends IWatcherRequest {
parsedPattern?: glob.ParsedPattern;
}
......@@ -40,6 +36,7 @@ export class ChokidarWatcherService implements IWatcherService {
private _watcherCount: number;
private _pollingInterval?: number;
private _usePolling?: boolean;
private _verboseLogging: boolean;
private spamCheckStartTime: number;
......@@ -52,8 +49,9 @@ export class ChokidarWatcherService implements IWatcherService {
private _onLogMessage = new Emitter<ILogMessage>();
readonly onLogMessage: Event<ILogMessage> = this._onLogMessage.event;
public watch(options: IWatcherOptions & IChockidarWatcherOptions): Event<IDiskFileChange[]> {
public watch(options: IWatcherOptions): Event<IDiskFileChange[]> {
this._pollingInterval = options.pollingInterval;
this._usePolling = options.usePolling;
this._watchers = Object.create(null);
this._watcherCount = 0;
return this.onWatchEvent;
......@@ -106,6 +104,10 @@ export class ChokidarWatcherService implements IWatcherService {
}
const pollingInterval = this._pollingInterval || 1000;
const usePolling = this._usePolling;
if (usePolling && this._verboseLogging) {
this.log(`Use polling instead of fs.watch: Polling interval ${pollingInterval} ms`);
}
const watcherOpts: chokidar.IOptions = {
ignoreInitial: true,
......@@ -113,6 +115,7 @@ export class ChokidarWatcherService implements IWatcherService {
followSymlinks: true, // this is the default of chokidar and supports file events through symlinks
interval: pollingInterval, // while not used in normal cases, if any error causes chokidar to fallback to polling, increase its intervals
binaryInterval: pollingInterval,
usePolling: usePolling,
disableGlobbing: true // fix https://github.com/Microsoft/vscode/issues/4586
};
......
......@@ -12,6 +12,8 @@ export interface IWatcherRequest {
}
export interface IWatcherOptions {
pollingInterval?: number;
usePolling?: boolean;
}
export interface IWatcherService {
......
......@@ -8,7 +8,7 @@ import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
import { IDiskFileChange, ILogMessage } from 'vs/workbench/services/files/node/watcher/watcher';
import { WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/unix/watcherIpc';
import { Disposable } from 'vs/base/common/lifecycle';
import { IWatcherRequest } from 'vs/workbench/services/files/node/watcher/unix/watcher';
import { IWatcherRequest, IWatcherOptions } from 'vs/workbench/services/files/node/watcher/unix/watcher';
import { getPathFromAmdModule } from 'vs/base/common/amd';
export class FileWatcher extends Disposable {
......@@ -22,7 +22,8 @@ export class FileWatcher extends Disposable {
private folders: IWatcherRequest[],
private onFileChanges: (changes: IDiskFileChange[]) => void,
private onLogMessage: (msg: ILogMessage) => void,
private verboseLogging: boolean
private verboseLogging: boolean,
private watcherOptions: IWatcherOptions = {}
) {
super();
......@@ -66,8 +67,7 @@ export class FileWatcher extends Disposable {
this.service.setVerboseLogging(this.verboseLogging);
const options = {};
this._register(this.service.watch(options)(e => !this.isDisposed && this.onFileChanges(e)));
this._register(this.service.watch(this.watcherOptions)(e => !this.isDisposed && this.onFileChanges(e)));
this._register(this.service.onLogMessage(m => this.onLogMessage(m)));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册