提交 ecc90f44 编写于 作者: J Joao Moreno

Merge remote-tracking branch 'origin/master'

......@@ -4,9 +4,9 @@ set -e
# setup nvm
if [[ "$OSTYPE" == "darwin"* ]]; then
export NVM_DIR=~/.nvm
source $(brew --prefix nvm)/nvm.sh
source $(brew --prefix nvm)/nvm.sh --no-use
else
source $NVM_DIR/nvm.sh
source $NVM_DIR/nvm.sh --no-use
fi
# install node
......
......@@ -21,7 +21,6 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import Event, { Emitter } from 'vs/base/common/event';
import { shell } from 'electron';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { isMacintosh } from 'vs/base/common/platform';
......@@ -36,6 +35,9 @@ export class FileService implements IFileService {
private static readonly NET_VERSION_ERROR = 'System.MissingMethodException';
private static readonly NET_VERSION_ERROR_IGNORE_KEY = 'ignoreNetVersionError';
private static readonly ENOSPC_ERROR = 'ENOSPC';
private static readonly ENOSPC_ERROR_IGNORE_KEY = 'ignoreEnospcError';
private raw: NodeFileService;
private toUnbind: IDisposable[];
......@@ -96,13 +98,17 @@ export class FileService implements IFileService {
return this._onAfterOperation.event;
}
private onFileServiceError(msg: string): void {
private onFileServiceError(error: string | Error): void {
const msg = error ? error.toString() : void 0;
if (!msg) {
return;
}
// Forward to unexpected error handler
errors.onUnexpectedError(msg);
// Detect if we run < .NET Framework 4.5 (TODO@ben remove with new watcher impl)
if (typeof msg === 'string' && msg.indexOf(FileService.NET_VERSION_ERROR) >= 0 && !this.storageService.getBoolean(FileService.NET_VERSION_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) {
if (msg.indexOf(FileService.NET_VERSION_ERROR) >= 0 && !this.storageService.getBoolean(FileService.NET_VERSION_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) {
this.messageService.show(Severity.Warning, <IMessageWithAction>{
message: nls.localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."),
actions: [
......@@ -120,6 +126,26 @@ export class FileService implements IFileService {
]
});
}
// Detect if we run into ENOSPC issues (TODO@ben remove with new watcher impl)
if (msg.indexOf(FileService.ENOSPC_ERROR) >= 0 && !this.storageService.getBoolean(FileService.ENOSPC_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) {
this.messageService.show(Severity.Warning, <IMessageWithAction>{
message: nls.localize('enospcError', "{0} is running out of file handles. Please follow the instructions link to resolve this issue.", product.nameLong),
actions: [
new Action('learnMore', nls.localize('learnMore', "Instructions"), null, true, () => {
window.open('https://go.microsoft.com/fwlink/?linkid=867693');
return TPromise.as(true);
}),
new Action('enospc.error.ignore', nls.localize('neverShowAgain', "Don't Show Again"), '', true, () => {
this.storageService.store(FileService.ENOSPC_ERROR_IGNORE_KEY, true, StorageScope.WORKSPACE);
return TPromise.as(null);
}),
CloseAction
]
});
}
}
private registerListeners(): void {
......
......@@ -10,7 +10,7 @@ import * as platform from 'vs/base/common/platform';
import * as watcher from 'vs/workbench/services/files/node/watcher/common';
import * as nsfw from 'nsfw';
import { IWatcherService, IWatcherRequest } from 'vs/workbench/services/files/node/watcher/nsfw/watcher';
import { TPromise, ProgressCallback, TValueCallback } from 'vs/base/common/winjs.base';
import { TPromise, ProgressCallback, TValueCallback, ErrorCallback } from 'vs/base/common/winjs.base';
import { ThrottledDelayer } from 'vs/base/common/async';
import { FileChangeType } from 'vs/platform/files/common/files';
import { normalizeNFC } from 'vs/base/common/strings';
......@@ -37,13 +37,16 @@ export class NsfwWatcherService implements IWatcherService {
private _pathWatchers: { [watchPath: string]: IPathWatcher } = {};
private _watcherPromise: TPromise<void>;
private _progressCallback: ProgressCallback;
private _errorCallback: ErrorCallback;
private _verboseLogging: boolean;
private enospcErrorLogged: boolean;
public initialize(verboseLogging: boolean): TPromise<void> {
this._verboseLogging = verboseLogging;
this._verboseLogging = true;
this._watcherPromise = new TPromise<void>((c, e, p) => {
this._errorCallback = e;
this._progressCallback = p;
});
return this._watcherPromise;
}
......@@ -58,6 +61,19 @@ export class NsfwWatcherService implements IWatcherService {
ignored: request.ignored
};
process.on('uncaughtException', e => {
// Specially handle ENOSPC errors that can happen when
// the watcher consumes so many file descriptors that
// we are running into a limit. We only want to warn
// once in this case to avoid log spam.
// See https://github.com/Microsoft/vscode/issues/7950
if (e === 'Inotify limit reached' && !this.enospcErrorLogged) {
this.enospcErrorLogged = true;
this._errorCallback(new Error('Inotify limit reached (ENOSPC)'));
}
});
nsfw(request.basePath, events => {
for (let i = 0; i < events.length; i++) {
const e = events[i];
......
......@@ -18,7 +18,7 @@ import strings = require('vs/base/common/strings');
import { realcaseSync } from 'vs/base/node/extfs';
import { isMacintosh } from 'vs/base/common/platform';
import watcher = require('vs/workbench/services/files/node/watcher/common');
import { IWatcherRequest, IWatcherService } from './watcher';
import { IWatcherRequest, IWatcherService } from 'vs/workbench/services/files/node/watcher/unix/watcher';
export class ChokidarWatcherService implements IWatcherService {
......@@ -27,6 +27,7 @@ export class ChokidarWatcherService implements IWatcherService {
private spamCheckStartTime: number;
private spamWarningLogged: boolean;
private enospcErrorLogged: boolean;
public watch(request: IWatcherRequest): TPromise<void> {
const watcherOpts: chokidar.IOptions = {
......@@ -138,7 +139,20 @@ export class ChokidarWatcherService implements IWatcherService {
chokidarWatcher.on('error', (error: Error) => {
if (error) {
console.error(error.toString());
// Specially handle ENOSPC errors that can happen when
// the watcher consumes so many file descriptors that
// we are running into a limit. We only want to warn
// once in this case to avoid log spam.
// See https://github.com/Microsoft/vscode/issues/7950
if ((<any>error).code === 'ENOSPC') {
if (!this.enospcErrorLogged) {
this.enospcErrorLogged = true;
e(new Error('Inotify limit reached (ENOSPC)'));
}
} else {
console.error(error.toString());
}
}
});
}, () => {
......
......@@ -7,7 +7,7 @@
import { TPromise } from 'vs/base/common/winjs.base';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWatcherRequest, IWatcherService } from './watcher';
import { IWatcherRequest, IWatcherService } from 'vs/workbench/services/files/node/watcher/unix/watcher';
export interface IWatcherChannel extends IChannel {
call(command: 'watch', request: IWatcherRequest): TPromise<void>;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册