redo --prof-startup
with the new protocol based profiler, also profile extension host startup
This commit is contained in:
parent
38311adcba
commit
52c2843cc4
|
@ -302,7 +302,6 @@ function packageTask(platform, arch, opts) {
|
|||
.pipe(util.cleanNodeModule('windows-foreground-love', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
||||
.pipe(util.cleanNodeModule('windows-process-tree', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
|
||||
.pipe(util.cleanNodeModule('gc-signals', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
|
||||
.pipe(util.cleanNodeModule('v8-profiler', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/index.js']))
|
||||
.pipe(util.cleanNodeModule('keytar', ['binding.gyp', 'build/**', 'src/**', 'script/**', 'node_modules/**'], ['**/*.node']))
|
||||
.pipe(util.cleanNodeModule('node-pty', ['binding.gyp', 'build/**', 'src/**', 'tools/**'], ['build/Release/**']))
|
||||
.pipe(util.cleanNodeModule('nsfw', ['binding.gyp', 'build/**', 'src/**', 'openpa/**', 'includes/**'], ['**/*.node', '**/*.a']))
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
"node-pty": "0.7.3",
|
||||
"nsfw": "1.0.16",
|
||||
"semver": "4.3.6",
|
||||
"v8-profiler": "jrieken/v8-profiler#vscode",
|
||||
"v8-inspect-profiler": "^0.0.6",
|
||||
"vscode-chokidar": "1.6.2",
|
||||
"vscode-debugprotocol": "1.25.0-pre.0",
|
||||
"vscode-ripgrep": "^0.6.0-patch.0.5",
|
||||
|
|
11
src/main.js
11
src/main.js
|
@ -5,13 +5,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
if (process.argv.indexOf('--prof-startup') >= 0) {
|
||||
var profiler = require('v8-profiler');
|
||||
var prefix = require('crypto').randomBytes(2).toString('hex');
|
||||
process.env.VSCODE_PROFILES_PREFIX = prefix;
|
||||
profiler.startProfiling('main', true);
|
||||
}
|
||||
|
||||
var perf = require('./vs/base/common/performance');
|
||||
perf.mark('main:started');
|
||||
|
||||
|
@ -122,6 +115,10 @@ function getNLSConfiguration() {
|
|||
}
|
||||
|
||||
function getNodeCachedDataDir() {
|
||||
// flag to disable cached data support
|
||||
if (process.argv.indexOf('--no-cached-data') > 0) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
// IEnvironmentService.isBuilt
|
||||
if (process.env['VSCODE_DEV']) {
|
||||
|
|
12
src/typings/v8-inspect-profiler.d.ts
vendored
Normal file
12
src/typings/v8-inspect-profiler.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
declare module 'v8-inspect-profiler' {
|
||||
|
||||
export interface Profile { }
|
||||
|
||||
export interface ProfilingSession {
|
||||
stop(afterDelay?: number): PromiseLike<Profile>;
|
||||
}
|
||||
|
||||
export function startProfiling(options: { port: number, tries?: number, retyWait?: number }): PromiseLike<ProfilingSession>;
|
||||
export function writeProfile(profile: Profile, name?: string): PromiseLike<void>;
|
||||
export function rewriteAbsolutePaths(profile, replaceWith?);
|
||||
}
|
|
@ -11,24 +11,24 @@ import net = require('net');
|
|||
* Given a start point and a max number of retries, will find a port that
|
||||
* is openable. Will return 0 in case no free port can be found.
|
||||
*/
|
||||
export function findFreePort(startPort: number, giveUpAfter: number, timeout: number, clb: (port: number) => void): void {
|
||||
export function findFreePort(startPort: number, giveUpAfter: number, timeout: number): Thenable<number> {
|
||||
let done = false;
|
||||
|
||||
const timeoutHandle = setTimeout(() => {
|
||||
if (!done) {
|
||||
done = true;
|
||||
return new Promise(resolve => {
|
||||
const timeoutHandle = setTimeout(() => {
|
||||
if (!done) {
|
||||
done = true;
|
||||
return resolve(0);
|
||||
}
|
||||
}, timeout);
|
||||
|
||||
return clb(0);
|
||||
}
|
||||
}, timeout);
|
||||
|
||||
doFindFreePort(startPort, giveUpAfter, (port) => {
|
||||
if (!done) {
|
||||
done = true;
|
||||
clearTimeout(timeoutHandle);
|
||||
|
||||
return clb(port);
|
||||
}
|
||||
doFindFreePort(startPort, giveUpAfter, (port) => {
|
||||
if (!done) {
|
||||
done = true;
|
||||
clearTimeout(timeoutHandle);
|
||||
return resolve(port);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { join, basename } from 'path';
|
||||
import { writeFile } from 'vs/base/node/pfs';
|
||||
|
||||
export function startProfiling(name: string): TPromise<boolean> {
|
||||
return lazyV8Profiler.value.then(profiler => {
|
||||
profiler.startProfiling(name);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
const _isRunningOutOfDev = process.env['VSCODE_DEV'];
|
||||
|
||||
export function stopProfiling(dir: string, prefix: string): TPromise<string> {
|
||||
return lazyV8Profiler.value.then(profiler => {
|
||||
return profiler.stopProfiling();
|
||||
}).then(profile => {
|
||||
return new TPromise<any>((resolve, reject) => {
|
||||
|
||||
// remove pii paths
|
||||
if (!_isRunningOutOfDev) {
|
||||
removePiiPaths(profile); // remove pii from our users
|
||||
}
|
||||
|
||||
profile.export(function (error, result) {
|
||||
profile.delete();
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
let filepath = join(dir, `${prefix}_${profile.title}.cpuprofile`);
|
||||
if (!_isRunningOutOfDev) {
|
||||
filepath += '.txt'; // github issues must be: txt, zip, png, gif
|
||||
}
|
||||
writeFile(filepath, result).then(() => resolve(filepath), reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function removePiiPaths(profile: Profile) {
|
||||
const stack = [profile.head];
|
||||
while (stack.length > 0) {
|
||||
const element = stack.pop();
|
||||
if (element.url) {
|
||||
const shortUrl = basename(element.url);
|
||||
if (element.url !== shortUrl) {
|
||||
element.url = `pii_removed/${shortUrl}`;
|
||||
}
|
||||
}
|
||||
if (element.children) {
|
||||
stack.push(...element.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare interface Profiler {
|
||||
startProfiling(name: string): void;
|
||||
stopProfiling(): Profile;
|
||||
}
|
||||
|
||||
export declare interface Profile {
|
||||
title: string;
|
||||
export(callback: (err, data) => void): void;
|
||||
delete(): void;
|
||||
head: ProfileSample;
|
||||
}
|
||||
|
||||
export declare interface ProfileSample {
|
||||
// bailoutReason:""
|
||||
// callUID:2333
|
||||
// children:Array[39]
|
||||
// functionName:"(root)"
|
||||
// hitCount:0
|
||||
// id:1
|
||||
// lineNumber:0
|
||||
// scriptId:0
|
||||
// url:""
|
||||
url: string;
|
||||
children: ProfileSample[];
|
||||
}
|
||||
|
||||
const lazyV8Profiler = new class {
|
||||
private _value: TPromise<Profiler>;
|
||||
get value() {
|
||||
if (!this._value) {
|
||||
this._value = new TPromise<Profiler>((resolve, reject) => {
|
||||
require(['v8-profiler'], resolve, reject);
|
||||
});
|
||||
}
|
||||
return this._value;
|
||||
}
|
||||
};
|
|
@ -18,7 +18,7 @@ suite('Ports', () => {
|
|||
}
|
||||
|
||||
// get an initial freeport >= 7000
|
||||
ports.findFreePort(7000, 100, 300000, (initialPort) => {
|
||||
ports.findFreePort(7000, 100, 300000).then(initialPort => {
|
||||
assert.ok(initialPort >= 7000);
|
||||
|
||||
// create a server to block this port
|
||||
|
@ -26,7 +26,7 @@ suite('Ports', () => {
|
|||
server.listen(initialPort, null, null, () => {
|
||||
|
||||
// once listening, find another free port and assert that the port is different from the opened one
|
||||
ports.findFreePort(7000, 50, 300000, (freePort) => {
|
||||
ports.findFreePort(7000, 50, 300000).then(freePort => {
|
||||
assert.ok(freePort >= 7000 && freePort !== initialPort);
|
||||
server.close();
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
import * as path from 'path';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { stopProfiling } from 'vs/base/node/profiler';
|
||||
import nls = require('vs/nls');
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { IStorageService } from 'vs/platform/storage/node/storage';
|
||||
|
@ -522,12 +521,6 @@ export class CodeWindow implements ICodeWindow {
|
|||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
||||
// (--prof-startup) save profile to disk
|
||||
const { profileStartup } = this.environmentService;
|
||||
if (profileStartup) {
|
||||
stopProfiling(profileStartup.dir, profileStartup.prefix).done(undefined, err => this.logService.error(err));
|
||||
}
|
||||
}
|
||||
|
||||
public reload(configuration?: IWindowConfiguration, cli?: ParsedArgs): void {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { spawn } from 'child_process';
|
||||
import { spawn, ChildProcess } from 'child_process';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { parseCLIProcessArgv, buildHelpMessage } from 'vs/platform/environment/node/argv';
|
||||
|
@ -15,6 +15,7 @@ import * as paths from 'path';
|
|||
import * as os from 'os';
|
||||
import { whenDeleted } from 'vs/base/node/pfs';
|
||||
import { writeFileAndFlushSync } from 'vs/base/node/extfs';
|
||||
import { findFreePort } from 'vs/base/node/ports';
|
||||
|
||||
function shouldSpawnCliProcess(argv: ParsedArgs): boolean {
|
||||
return !!argv['install-source']
|
||||
|
@ -27,7 +28,7 @@ interface IMainCli {
|
|||
main: (argv: ParsedArgs) => TPromise<void>;
|
||||
}
|
||||
|
||||
export function main(argv: string[]): TPromise<void> {
|
||||
export async function main(argv: string[]): TPromise<any> {
|
||||
let args: ParsedArgs;
|
||||
|
||||
try {
|
||||
|
@ -53,8 +54,16 @@ export function main(argv: string[]): TPromise<void> {
|
|||
|
||||
delete env['ELECTRON_RUN_AS_NODE'];
|
||||
|
||||
let processCallbacks: ((child: ChildProcess) => Thenable<any>)[] = [];
|
||||
|
||||
if (args.verbose) {
|
||||
env['ELECTRON_ENABLE_LOGGING'] = '1';
|
||||
|
||||
processCallbacks.push(child => {
|
||||
child.stdout.on('data', (data: Buffer) => console.log(data.toString('utf8').trim()));
|
||||
child.stderr.on('data', (data: Buffer) => console.log(data.toString('utf8').trim()));
|
||||
return new TPromise<void>(c => child.once('exit', () => c(null)));
|
||||
});
|
||||
}
|
||||
|
||||
// If we are started with --wait create a random temporary file
|
||||
|
@ -82,6 +91,50 @@ export function main(argv: string[]): TPromise<void> {
|
|||
}
|
||||
}
|
||||
|
||||
// If we have been started with `--prof-startup` we need to find free ports to profile
|
||||
// the main process, the renderer, and the extension host. We also disable v8 cached data
|
||||
// to get better profile traces. Last, we listen on stdout for a signal that tells us to
|
||||
// stop profiling.
|
||||
if (args['prof-startup']) {
|
||||
|
||||
const portMain = await findFreePort(9222, 10, 6000);
|
||||
const portRenderer = await findFreePort(portMain + 1, 10, 6000);
|
||||
const portExthost = await findFreePort(portRenderer + 1, 10, 6000);
|
||||
|
||||
if (!portMain || !portRenderer || !portExthost) {
|
||||
console.error('Failed to find free ports for profiler to connect to do.');
|
||||
return;
|
||||
}
|
||||
|
||||
const filenamePrefix = paths.join(os.homedir(), Math.random().toString(16).slice(-4));
|
||||
|
||||
argv.push(`--inspect-brk=${portMain}`);
|
||||
argv.push(`--remote-debugging-port=${portRenderer}`);
|
||||
argv.push(`--inspect-brk-extensions=${portExthost}`);
|
||||
argv.push(`--prof-startup-prefix`, filenamePrefix);
|
||||
argv.push(`--no-cached-data`);
|
||||
|
||||
writeFileAndFlushSync(filenamePrefix, argv.slice(-6).join('|'));
|
||||
|
||||
processCallbacks.push(async child => {
|
||||
|
||||
// load and start profiler
|
||||
const profiler = await import('v8-inspect-profiler');
|
||||
const main = await profiler.startProfiling({ port: portMain });
|
||||
const renderer = await profiler.startProfiling({ port: portRenderer, tries: 200 });
|
||||
const extHost = await profiler.startProfiling({ port: portExthost, tries: 300 });
|
||||
|
||||
// wait for the renderer to delete the
|
||||
// marker file
|
||||
whenDeleted(filenamePrefix);
|
||||
|
||||
// finally stop profiling and save profiles to disk
|
||||
await profiler.writeProfile(await main.stop(), `${filenamePrefix}-main.cpuprofile`);
|
||||
await profiler.writeProfile(await renderer.stop(), `${filenamePrefix}-renderer.cpuprofile`);
|
||||
await profiler.writeProfile(await extHost.stop(), `${filenamePrefix}-exthost.cpuprofile`);
|
||||
});
|
||||
}
|
||||
|
||||
const options = {
|
||||
detached: true,
|
||||
env
|
||||
|
@ -93,15 +146,6 @@ export function main(argv: string[]): TPromise<void> {
|
|||
|
||||
const child = spawn(process.execPath, argv.slice(2), options);
|
||||
|
||||
if (args.verbose) {
|
||||
child.stdout.on('data', (data: Buffer) => console.log(data.toString('utf8').trim()));
|
||||
child.stderr.on('data', (data: Buffer) => console.log(data.toString('utf8').trim()));
|
||||
}
|
||||
|
||||
if (args.verbose) {
|
||||
return new TPromise<void>(c => child.once('exit', () => c(null)));
|
||||
}
|
||||
|
||||
if (args.wait && waitMarkerFilePath) {
|
||||
return new TPromise<void>(c => {
|
||||
|
||||
|
@ -112,6 +156,8 @@ export function main(argv: string[]): TPromise<void> {
|
|||
whenDeleted(waitMarkerFilePath).done(c, c);
|
||||
});
|
||||
}
|
||||
|
||||
return TPromise.join(processCallbacks.map(callback => callback(child)));
|
||||
}
|
||||
|
||||
return TPromise.as(null);
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface ParsedArgs {
|
|||
'user-data-dir'?: string;
|
||||
performance?: boolean;
|
||||
'prof-startup'?: string;
|
||||
'prof-startup-prefix'?: string;
|
||||
verbose?: boolean;
|
||||
logExtensionHostCommunication?: boolean;
|
||||
'disable-extensions'?: boolean;
|
||||
|
@ -100,7 +101,6 @@ export interface IEnvironmentService {
|
|||
verbose: boolean;
|
||||
wait: boolean;
|
||||
performance: boolean;
|
||||
profileStartup: { prefix: string, dir: string } | undefined;
|
||||
|
||||
skipGettingStarted: boolean | undefined;
|
||||
|
||||
|
|
|
@ -118,18 +118,6 @@ export class EnvironmentService implements IEnvironmentService {
|
|||
|
||||
get performance(): boolean { return this._args.performance; }
|
||||
|
||||
@memoize
|
||||
get profileStartup(): { prefix: string, dir: string } | undefined {
|
||||
if (this._args['prof-startup']) {
|
||||
return {
|
||||
prefix: process.env.VSCODE_PROFILES_PREFIX,
|
||||
dir: os.homedir()
|
||||
};
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@memoize
|
||||
get mainIPCHandle(): string { return getIPCHandle(this.userDataPath, 'main'); }
|
||||
|
||||
|
|
|
@ -7,11 +7,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
if (window.location.search.indexOf('prof-startup') >= 0) {
|
||||
var profiler = require('v8-profiler');
|
||||
profiler.startProfiling('renderer', true);
|
||||
}
|
||||
|
||||
/*global window,document,define,Monaco_Loader_Init*/
|
||||
|
||||
const perf = require('../../../base/common/performance');
|
||||
|
|
|
@ -15,10 +15,10 @@ import { IWorkbenchContributionsRegistry, IWorkbenchContribution, Extensions } f
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ReportPerformanceIssueAction } from 'vs/workbench/electron-browser/actions';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { join } from 'path';
|
||||
import { join, dirname } from 'path';
|
||||
import { localize } from 'vs/nls';
|
||||
import { readdir } from 'vs/base/node/pfs';
|
||||
import { stopProfiling } from 'vs/base/node/profiler';
|
||||
import { readdir, del, readFile } from 'vs/base/node/pfs';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
|
||||
class StartupProfiler implements IWorkbenchContribution {
|
||||
|
||||
|
@ -31,55 +31,64 @@ class StartupProfiler implements IWorkbenchContribution {
|
|||
@IExtensionService extensionService: IExtensionService,
|
||||
) {
|
||||
// wait for everything to be ready
|
||||
extensionService.whenInstalledExtensionsRegistered().then(() => {
|
||||
Promise.all([
|
||||
lifecycleService.when(LifecyclePhase.Eventually),
|
||||
extensionService.whenInstalledExtensionsRegistered()
|
||||
]).then(() => {
|
||||
this._stopProfiling();
|
||||
});
|
||||
}
|
||||
|
||||
private _stopProfiling(): void {
|
||||
|
||||
const { profileStartup } = this._environmentService;
|
||||
if (!profileStartup) {
|
||||
const profileFilenamePrefix = this._environmentService.args['prof-startup-prefix'];
|
||||
if (!profileFilenamePrefix) {
|
||||
return;
|
||||
}
|
||||
|
||||
stopProfiling(profileStartup.dir, profileStartup.prefix).then(() => {
|
||||
readdir(profileStartup.dir).then(files => {
|
||||
return files.filter(value => value.indexOf(profileStartup.prefix) === 0);
|
||||
}).then(files => {
|
||||
const profileFiles = files.reduce((prev, cur) => `${prev}${join(profileStartup.dir, cur)}\n`, '\n');
|
||||
const dir = dirname(profileFilenamePrefix);
|
||||
const prefix = basename(profileFilenamePrefix);
|
||||
|
||||
const primaryButton = this._messageService.confirmSync({
|
||||
type: 'info',
|
||||
message: localize('prof.message', "Successfully created profiles."),
|
||||
detail: localize('prof.detail', "Please create an issue and manually attach the following files:\n{0}", profileFiles),
|
||||
primaryButton: localize('prof.restartAndFileIssue', "Create Issue and Restart"),
|
||||
secondaryButton: localize('prof.restart', "Restart")
|
||||
const removeArgs: string[] = ['--prof-startup'];
|
||||
const markerFile = readFile(profileFilenamePrefix).then(value => removeArgs.push(...value.toString().split('|')))
|
||||
.then(() => del(profileFilenamePrefix))
|
||||
.then(() => TPromise.timeout(1000));
|
||||
|
||||
markerFile.then(() => {
|
||||
return readdir(dir).then(files => files.filter(value => value.indexOf(prefix) === 0));
|
||||
}).then(files => {
|
||||
const profileFiles = files.reduce((prev, cur) => `${prev}${join(dir, cur)}\n`, '\n');
|
||||
|
||||
const primaryButton = this._messageService.confirmSync({
|
||||
type: 'info',
|
||||
message: localize('prof.message', "Successfully created profiles."),
|
||||
detail: localize('prof.detail', "Please create an issue and manually attach the following files:\n{0}", profileFiles),
|
||||
primaryButton: localize('prof.restartAndFileIssue', "Create Issue and Restart"),
|
||||
secondaryButton: localize('prof.restart', "Restart")
|
||||
});
|
||||
|
||||
if (primaryButton) {
|
||||
const action = this._instantiationService.createInstance(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL);
|
||||
TPromise.join<any>([
|
||||
this._windowsService.showItemInFolder(join(dir, files[0])),
|
||||
action.run(`:warning: Make sure to **attach** these files from your *home*-directory: :warning:\n${files.map(file => `-\`${file}\``).join('\n')}`)
|
||||
]).then(() => {
|
||||
// keep window stable until restart is selected
|
||||
this._messageService.confirmSync({
|
||||
type: 'info',
|
||||
message: localize('prof.thanks', "Thanks for helping us."),
|
||||
detail: localize('prof.detail.restart', "A final restart is required to continue to use '{0}'. Again, thank you for your contribution.", this._environmentService.appNameLong),
|
||||
primaryButton: localize('prof.restart', "Restart"),
|
||||
secondaryButton: null
|
||||
});
|
||||
// now we are ready to restart
|
||||
this._windowsService.relaunch({ removeArgs });
|
||||
});
|
||||
|
||||
if (primaryButton) {
|
||||
const action = this._instantiationService.createInstance(ReportPerformanceIssueAction, ReportPerformanceIssueAction.ID, ReportPerformanceIssueAction.LABEL);
|
||||
TPromise.join<any>([
|
||||
this._windowsService.showItemInFolder(join(profileStartup.dir, files[0])),
|
||||
action.run(`:warning: Make sure to **attach** these files from your *home*-directory: :warning:\n${files.map(file => `-\`${file}\``).join('\n')}`)
|
||||
]).then(() => {
|
||||
// keep window stable until restart is selected
|
||||
this._messageService.confirmSync({
|
||||
type: 'info',
|
||||
message: localize('prof.thanks', "Thanks for helping us."),
|
||||
detail: localize('prof.detail.restart', "A final restart is required to continue to use '{0}'. Again, thank you for your contribution.", this._environmentService.appNameLong),
|
||||
primaryButton: localize('prof.restart', "Restart"),
|
||||
secondaryButton: null
|
||||
});
|
||||
// now we are ready to restart
|
||||
this._windowsService.relaunch({ removeArgs: ['--prof-startup'] });
|
||||
});
|
||||
|
||||
} else {
|
||||
// simply restart
|
||||
this._windowsService.relaunch({ removeArgs: ['--prof-startup'] });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// simply restart
|
||||
this._windowsService.relaunch({ removeArgs });
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,7 +265,7 @@ export class ExtensionHostProcessWorker {
|
|||
return TPromise.wrap<number>(0);
|
||||
}
|
||||
return new TPromise<number>((c, e) => {
|
||||
findFreePort(extensionHostPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */, (port) => {
|
||||
return findFreePort(extensionHostPort, 10 /* try 10 ports */, 5000 /* try up to 5 seconds */).then(port => {
|
||||
if (!port) {
|
||||
console.warn('%c[Extension Host] %cCould not find a free port for debugging', 'color: blue', 'color: black');
|
||||
return c(void 0);
|
||||
|
|
41
yarn.lock
41
yarn.lock
|
@ -252,6 +252,10 @@ async-each@^1.0.0:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
|
||||
|
||||
async-limiter@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8"
|
||||
|
||||
async@1.x, async@^1.4.0, async@^1.5.0:
|
||||
version "1.5.2"
|
||||
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
|
||||
|
@ -580,6 +584,13 @@ cheerio@^1.0.0-rc.1:
|
|||
lodash "^4.15.0"
|
||||
parse5 "^3.0.1"
|
||||
|
||||
chrome-remote-interface@^0.25.3:
|
||||
version "0.25.3"
|
||||
resolved "https://registry.yarnpkg.com/chrome-remote-interface/-/chrome-remote-interface-0.25.3.tgz#b692ae538cd5af3a6dd285636bfab3d29a7006c1"
|
||||
dependencies:
|
||||
commander "2.11.x"
|
||||
ws "3.3.x"
|
||||
|
||||
ci-info@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.1.tgz#47b44df118c48d2597b56d342e7e25791060171a"
|
||||
|
@ -741,6 +752,10 @@ commander@0.6.1:
|
|||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06"
|
||||
|
||||
commander@2.11.x, commander@^2.8.1, commander@^2.9.0, commander@~2.11.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
|
||||
|
||||
commander@2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873"
|
||||
|
@ -751,10 +766,6 @@ commander@2.8.x:
|
|||
dependencies:
|
||||
graceful-readlink ">= 1.0.0"
|
||||
|
||||
commander@^2.8.1, commander@^2.9.0, commander@~2.11.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563"
|
||||
|
||||
commandpost@^1.0.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/commandpost/-/commandpost-1.2.1.tgz#2e9c4c7508b9dc704afefaa91cab92ee6054cc68"
|
||||
|
@ -3719,7 +3730,7 @@ nan@^2.0.0, nan@^2.6.2:
|
|||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
|
||||
|
||||
nan@^2.0.9, nan@^2.3.0, nan@^2.3.2:
|
||||
nan@^2.0.9, nan@^2.3.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232"
|
||||
|
||||
|
@ -5466,6 +5477,10 @@ uglify-to-browserify@~1.0.0:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
|
||||
|
||||
ultron@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.0.tgz#b07a2e6a541a815fc6a34ccd4533baec307ca864"
|
||||
|
||||
unc-path-regex@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
|
||||
|
@ -5559,11 +5574,11 @@ uuid@^3.0.0, uuid@^3.1.0:
|
|||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
|
||||
|
||||
v8-profiler@jrieken/v8-profiler#vscode:
|
||||
version "5.6.5"
|
||||
resolved "https://codeload.github.com/jrieken/v8-profiler/tar.gz/5e4a336693e1d5b079c7aecd286a1abcfbc10421"
|
||||
v8-inspect-profiler@^0.0.6:
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/v8-inspect-profiler/-/v8-inspect-profiler-0.0.6.tgz#7885de7e9c3304118bde25d5b3d6ec5116467f2c"
|
||||
dependencies:
|
||||
nan "^2.3.2"
|
||||
chrome-remote-interface "^0.25.3"
|
||||
|
||||
v8flags@^2.0.2:
|
||||
version "2.1.1"
|
||||
|
@ -5850,6 +5865,14 @@ write@^0.2.1:
|
|||
dependencies:
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
ws@3.3.x:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.2.tgz#96c1d08b3fefda1d5c1e33700d3bfaa9be2d5608"
|
||||
dependencies:
|
||||
async-limiter "~1.0.0"
|
||||
safe-buffer "~5.1.0"
|
||||
ultron "~1.1.0"
|
||||
|
||||
xml-name-validator@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-1.0.0.tgz#dcf82ee092322951ef8cc1ba596c9cbfd14a83f1"
|
||||
|
|
Loading…
Reference in a new issue