Skip to content

Commit ecc90f4

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 4fd6a62 + 7f5c6ff commit ecc90f4

5 files changed

Lines changed: 67 additions & 11 deletions

File tree

build/tfs/common/node.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ set -e
44
# setup nvm
55
if [[ "$OSTYPE" == "darwin"* ]]; then
66
export NVM_DIR=~/.nvm
7-
source $(brew --prefix nvm)/nvm.sh
7+
source $(brew --prefix nvm)/nvm.sh --no-use
88
else
9-
source $NVM_DIR/nvm.sh
9+
source $NVM_DIR/nvm.sh --no-use
1010
fi
1111

1212
# install node

src/vs/workbench/services/files/electron-browser/fileService.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
2121
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
2222
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
2323
import Event, { Emitter } from 'vs/base/common/event';
24-
2524
import { shell } from 'electron';
2625
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
2726
import { isMacintosh } from 'vs/base/common/platform';
@@ -36,6 +35,9 @@ export class FileService implements IFileService {
3635
private static readonly NET_VERSION_ERROR = 'System.MissingMethodException';
3736
private static readonly NET_VERSION_ERROR_IGNORE_KEY = 'ignoreNetVersionError';
3837

38+
private static readonly ENOSPC_ERROR = 'ENOSPC';
39+
private static readonly ENOSPC_ERROR_IGNORE_KEY = 'ignoreEnospcError';
40+
3941
private raw: NodeFileService;
4042

4143
private toUnbind: IDisposable[];
@@ -96,13 +98,17 @@ export class FileService implements IFileService {
9698
return this._onAfterOperation.event;
9799
}
98100

99-
private onFileServiceError(msg: string): void {
101+
private onFileServiceError(error: string | Error): void {
102+
const msg = error ? error.toString() : void 0;
103+
if (!msg) {
104+
return;
105+
}
100106

101107
// Forward to unexpected error handler
102108
errors.onUnexpectedError(msg);
103109

104110
// Detect if we run < .NET Framework 4.5 (TODO@ben remove with new watcher impl)
105-
if (typeof msg === 'string' && msg.indexOf(FileService.NET_VERSION_ERROR) >= 0 && !this.storageService.getBoolean(FileService.NET_VERSION_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) {
111+
if (msg.indexOf(FileService.NET_VERSION_ERROR) >= 0 && !this.storageService.getBoolean(FileService.NET_VERSION_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) {
106112
this.messageService.show(Severity.Warning, <IMessageWithAction>{
107113
message: nls.localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."),
108114
actions: [
@@ -120,6 +126,26 @@ export class FileService implements IFileService {
120126
]
121127
});
122128
}
129+
130+
// Detect if we run into ENOSPC issues (TODO@ben remove with new watcher impl)
131+
if (msg.indexOf(FileService.ENOSPC_ERROR) >= 0 && !this.storageService.getBoolean(FileService.ENOSPC_ERROR_IGNORE_KEY, StorageScope.WORKSPACE)) {
132+
this.messageService.show(Severity.Warning, <IMessageWithAction>{
133+
message: nls.localize('enospcError', "{0} is running out of file handles. Please follow the instructions link to resolve this issue.", product.nameLong),
134+
actions: [
135+
new Action('learnMore', nls.localize('learnMore', "Instructions"), null, true, () => {
136+
window.open('https://go.microsoft.com/fwlink/?linkid=867693');
137+
138+
return TPromise.as(true);
139+
}),
140+
new Action('enospc.error.ignore', nls.localize('neverShowAgain', "Don't Show Again"), '', true, () => {
141+
this.storageService.store(FileService.ENOSPC_ERROR_IGNORE_KEY, true, StorageScope.WORKSPACE);
142+
143+
return TPromise.as(null);
144+
}),
145+
CloseAction
146+
]
147+
});
148+
}
123149
}
124150

125151
private registerListeners(): void {

src/vs/workbench/services/files/node/watcher/nsfw/nsfwWatcherService.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import * as platform from 'vs/base/common/platform';
1010
import * as watcher from 'vs/workbench/services/files/node/watcher/common';
1111
import * as nsfw from 'nsfw';
1212
import { IWatcherService, IWatcherRequest } from 'vs/workbench/services/files/node/watcher/nsfw/watcher';
13-
import { TPromise, ProgressCallback, TValueCallback } from 'vs/base/common/winjs.base';
13+
import { TPromise, ProgressCallback, TValueCallback, ErrorCallback } from 'vs/base/common/winjs.base';
1414
import { ThrottledDelayer } from 'vs/base/common/async';
1515
import { FileChangeType } from 'vs/platform/files/common/files';
1616
import { normalizeNFC } from 'vs/base/common/strings';
@@ -37,13 +37,16 @@ export class NsfwWatcherService implements IWatcherService {
3737
private _pathWatchers: { [watchPath: string]: IPathWatcher } = {};
3838
private _watcherPromise: TPromise<void>;
3939
private _progressCallback: ProgressCallback;
40+
private _errorCallback: ErrorCallback;
4041
private _verboseLogging: boolean;
41-
42+
private enospcErrorLogged: boolean;
4243

4344
public initialize(verboseLogging: boolean): TPromise<void> {
44-
this._verboseLogging = verboseLogging;
45+
this._verboseLogging = true;
4546
this._watcherPromise = new TPromise<void>((c, e, p) => {
47+
this._errorCallback = e;
4648
this._progressCallback = p;
49+
4750
});
4851
return this._watcherPromise;
4952
}
@@ -58,6 +61,19 @@ export class NsfwWatcherService implements IWatcherService {
5861
ignored: request.ignored
5962
};
6063

64+
process.on('uncaughtException', e => {
65+
66+
// Specially handle ENOSPC errors that can happen when
67+
// the watcher consumes so many file descriptors that
68+
// we are running into a limit. We only want to warn
69+
// once in this case to avoid log spam.
70+
// See https://github.com/Microsoft/vscode/issues/7950
71+
if (e === 'Inotify limit reached' && !this.enospcErrorLogged) {
72+
this.enospcErrorLogged = true;
73+
this._errorCallback(new Error('Inotify limit reached (ENOSPC)'));
74+
}
75+
});
76+
6177
nsfw(request.basePath, events => {
6278
for (let i = 0; i < events.length; i++) {
6379
const e = events[i];

src/vs/workbench/services/files/node/watcher/unix/chokidarWatcherService.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import strings = require('vs/base/common/strings');
1818
import { realcaseSync } from 'vs/base/node/extfs';
1919
import { isMacintosh } from 'vs/base/common/platform';
2020
import watcher = require('vs/workbench/services/files/node/watcher/common');
21-
import { IWatcherRequest, IWatcherService } from './watcher';
21+
import { IWatcherRequest, IWatcherService } from 'vs/workbench/services/files/node/watcher/unix/watcher';
2222

2323
export class ChokidarWatcherService implements IWatcherService {
2424

@@ -27,6 +27,7 @@ export class ChokidarWatcherService implements IWatcherService {
2727

2828
private spamCheckStartTime: number;
2929
private spamWarningLogged: boolean;
30+
private enospcErrorLogged: boolean;
3031

3132
public watch(request: IWatcherRequest): TPromise<void> {
3233
const watcherOpts: chokidar.IOptions = {
@@ -138,7 +139,20 @@ export class ChokidarWatcherService implements IWatcherService {
138139

139140
chokidarWatcher.on('error', (error: Error) => {
140141
if (error) {
141-
console.error(error.toString());
142+
143+
// Specially handle ENOSPC errors that can happen when
144+
// the watcher consumes so many file descriptors that
145+
// we are running into a limit. We only want to warn
146+
// once in this case to avoid log spam.
147+
// See https://github.com/Microsoft/vscode/issues/7950
148+
if ((<any>error).code === 'ENOSPC') {
149+
if (!this.enospcErrorLogged) {
150+
this.enospcErrorLogged = true;
151+
e(new Error('Inotify limit reached (ENOSPC)'));
152+
}
153+
} else {
154+
console.error(error.toString());
155+
}
142156
}
143157
});
144158
}, () => {

src/vs/workbench/services/files/node/watcher/unix/watcherIpc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import { TPromise } from 'vs/base/common/winjs.base';
99
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
10-
import { IWatcherRequest, IWatcherService } from './watcher';
10+
import { IWatcherRequest, IWatcherService } from 'vs/workbench/services/files/node/watcher/unix/watcher';
1111

1212
export interface IWatcherChannel extends IChannel {
1313
call(command: 'watch', request: IWatcherRequest): TPromise<void>;

0 commit comments

Comments
 (0)