mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-30 17:23:29 -05:00
Merge from master
This commit is contained in:
@@ -2,16 +2,17 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { NodeCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner';
|
||||
import { LanguagePackCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { StorageDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner';
|
||||
|
||||
export function createSharedProcessContributions(service: IInstantiationService): IDisposable {
|
||||
return combinedDisposable([
|
||||
service.createInstance(NodeCachedDataCleaner),
|
||||
service.createInstance(LanguagePackCachedDataCleaner)
|
||||
service.createInstance(LanguagePackCachedDataCleaner),
|
||||
service.createInstance(StorageDataCleaner)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as pfs from 'vs/base/node/pfs';
|
||||
@@ -51,7 +50,7 @@ export class LanguagePackCachedDataCleaner {
|
||||
}
|
||||
|
||||
private _manageCachedDataSoon(): void {
|
||||
let handle = setTimeout(async () => {
|
||||
let handle: any = setTimeout(async () => {
|
||||
handle = undefined;
|
||||
this._logService.info('Starting to clean up unused language packs.');
|
||||
const maxAge = product.nameLong.indexOf('Insiders') >= 0
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { basename, dirname, join } from 'path';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { join, basename, dirname } from 'path';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { readdir, rimraf, stat } from 'vs/base/node/pfs';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import product from 'vs/platform/node/product';
|
||||
@@ -43,13 +41,13 @@ export class NodeCachedDataCleaner {
|
||||
const nodeCachedDataRootDir = dirname(this._environmentService.nodeCachedDataDir);
|
||||
const nodeCachedDataCurrent = basename(this._environmentService.nodeCachedDataDir);
|
||||
|
||||
let handle = setTimeout(() => {
|
||||
let handle: any = setTimeout(() => {
|
||||
handle = undefined;
|
||||
|
||||
readdir(nodeCachedDataRootDir).then(entries => {
|
||||
|
||||
const now = Date.now();
|
||||
const deletes: TPromise<any>[] = [];
|
||||
const deletes: Thenable<any>[] = [];
|
||||
|
||||
entries.forEach(entry => {
|
||||
// name check
|
||||
@@ -72,9 +70,9 @@ export class NodeCachedDataCleaner {
|
||||
}
|
||||
});
|
||||
|
||||
return TPromise.join(deletes);
|
||||
return Promise.all(deletes);
|
||||
|
||||
}).done(undefined, onUnexpectedError);
|
||||
}).then(undefined, onUnexpectedError);
|
||||
|
||||
}, 30 * 1000);
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { join } from 'path';
|
||||
import { readdir, readFile, rimraf } from 'vs/base/node/pfs';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IBackupWorkspacesFormat } from 'vs/platform/backup/common/backup';
|
||||
|
||||
export class StorageDataCleaner extends Disposable {
|
||||
|
||||
// Workspace/Folder storage names are MD5 hashes (128bits / 4 due to hex presentation)
|
||||
private static NON_EMPTY_WORKSPACE_ID_LENGTH = 128 / 4;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService private environmentService: IEnvironmentService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.cleanUpStorageSoon();
|
||||
}
|
||||
|
||||
private cleanUpStorageSoon(): void {
|
||||
let handle: any = setTimeout(() => {
|
||||
handle = void 0;
|
||||
|
||||
// Leverage the backup workspace file to find out which empty workspace is currently in use to
|
||||
// determine which empty workspace storage can safely be deleted
|
||||
readFile(this.environmentService.backupWorkspacesPath, 'utf8').then(contents => {
|
||||
const workspaces = JSON.parse(contents) as IBackupWorkspacesFormat;
|
||||
const emptyWorkspaces = workspaces.emptyWorkspaceInfos.map(info => info.backupFolder);
|
||||
|
||||
// Read all workspace storage folders that exist
|
||||
return readdir(this.environmentService.workspaceStorageHome).then(storageFolders => {
|
||||
const deletes: Promise<void>[] = [];
|
||||
|
||||
storageFolders.forEach(storageFolder => {
|
||||
if (storageFolder.length === StorageDataCleaner.NON_EMPTY_WORKSPACE_ID_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (emptyWorkspaces.indexOf(storageFolder) === -1) {
|
||||
deletes.push(rimraf(join(this.environmentService.workspaceStorageHome, storageFolder)));
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(deletes);
|
||||
});
|
||||
}).then(null, onUnexpectedError);
|
||||
}, 30 * 1000);
|
||||
|
||||
this._register(toDisposable(() => clearTimeout(handle)));
|
||||
}
|
||||
}
|
||||
@@ -3,168 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const bootstrap = require('../../../../bootstrap');
|
||||
const bootstrapWindow = require('../../../../bootstrap-window');
|
||||
|
||||
function assign(destination, source) {
|
||||
return Object.keys(source)
|
||||
.reduce(function (r, key) { r[key] = source[key]; return r; }, destination);
|
||||
}
|
||||
// Avoid Monkey Patches from Application Insights
|
||||
bootstrap.avoidMonkeyPatchFromAppInsights();
|
||||
|
||||
function parseURLQueryArgs() {
|
||||
const search = window.location.search || '';
|
||||
|
||||
return search.split(/[?&]/)
|
||||
.filter(function (param) { return !!param; })
|
||||
.map(function (param) { return param.split('='); })
|
||||
.filter(function (param) { return param.length === 2; })
|
||||
.reduce(function (r, param) { r[param[0]] = decodeURIComponent(param[1]); return r; }, {});
|
||||
}
|
||||
|
||||
function createScript(src, onload) {
|
||||
const script = document.createElement('script');
|
||||
script.src = src;
|
||||
script.addEventListener('load', onload);
|
||||
|
||||
const head = document.getElementsByTagName('head')[0];
|
||||
head.insertBefore(script, head.lastChild);
|
||||
}
|
||||
|
||||
function uriFromPath(_path) {
|
||||
var pathName = path.resolve(_path).replace(/\\/g, '/');
|
||||
if (pathName.length > 0 && pathName.charAt(0) !== '/') {
|
||||
pathName = '/' + pathName;
|
||||
}
|
||||
|
||||
return encodeURI('file://' + pathName);
|
||||
}
|
||||
|
||||
function readFile(file) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
fs.readFile(file, 'utf8', function(err, data) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(data);
|
||||
});
|
||||
bootstrapWindow.load(['vs/code/electron-browser/sharedProcess/sharedProcessMain'], function (sharedProcess, configuration) {
|
||||
sharedProcess.startup({
|
||||
machineId: configuration.machineId
|
||||
});
|
||||
}
|
||||
|
||||
const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c()));
|
||||
|
||||
function main() {
|
||||
const args = parseURLQueryArgs();
|
||||
const configuration = JSON.parse(args['config'] || '{}') || {};
|
||||
|
||||
//#region Add support for using node_modules.asar
|
||||
(function () {
|
||||
const path = require('path');
|
||||
const Module = require('module');
|
||||
let NODE_MODULES_PATH = path.join(configuration.appRoot, 'node_modules');
|
||||
if (/[a-z]\:/.test(NODE_MODULES_PATH)) {
|
||||
// Make drive letter uppercase
|
||||
NODE_MODULES_PATH = NODE_MODULES_PATH.charAt(0).toUpperCase() + NODE_MODULES_PATH.substr(1);
|
||||
}
|
||||
const NODE_MODULES_ASAR_PATH = NODE_MODULES_PATH + '.asar';
|
||||
|
||||
const originalResolveLookupPaths = Module._resolveLookupPaths;
|
||||
Module._resolveLookupPaths = function (request, parent, newReturn) {
|
||||
const result = originalResolveLookupPaths(request, parent, newReturn);
|
||||
|
||||
const paths = newReturn ? result : result[1];
|
||||
for (let i = 0, len = paths.length; i < len; i++) {
|
||||
if (paths[i] === NODE_MODULES_PATH) {
|
||||
paths.splice(i, 0, NODE_MODULES_ASAR_PATH);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
//#endregion
|
||||
|
||||
// Correctly inherit the parent's environment
|
||||
assign(process.env, configuration.userEnv);
|
||||
|
||||
// Get the nls configuration into the process.env as early as possible.
|
||||
var nlsConfig = { availableLanguages: {} };
|
||||
const config = process.env['VSCODE_NLS_CONFIG'];
|
||||
if (config) {
|
||||
process.env['VSCODE_NLS_CONFIG'] = config;
|
||||
try {
|
||||
nlsConfig = JSON.parse(config);
|
||||
} catch (e) { /*noop*/ }
|
||||
}
|
||||
|
||||
if (nlsConfig._resolvedLanguagePackCoreLocation) {
|
||||
let bundles = Object.create(null);
|
||||
nlsConfig.loadBundle = function(bundle, language, cb) {
|
||||
let result = bundles[bundle];
|
||||
if (result) {
|
||||
cb(undefined, result);
|
||||
return;
|
||||
}
|
||||
let bundleFile = path.join(nlsConfig._resolvedLanguagePackCoreLocation, bundle.replace(/\//g, '!') + '.nls.json');
|
||||
readFile(bundleFile).then(function (content) {
|
||||
let json = JSON.parse(content);
|
||||
bundles[bundle] = json;
|
||||
cb(undefined, json);
|
||||
}).catch((error) => {
|
||||
try {
|
||||
if (nlsConfig._corruptedFile) {
|
||||
writeFile(nlsConfig._corruptedFile, 'corrupted').catch(function (error) { console.error(error); });
|
||||
}
|
||||
} finally {
|
||||
cb(error, undefined);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
var locale = nlsConfig.availableLanguages['*'] || 'en';
|
||||
if (locale === 'zh-tw') {
|
||||
locale = 'zh-Hant';
|
||||
} else if (locale === 'zh-cn') {
|
||||
locale = 'zh-Hans';
|
||||
}
|
||||
|
||||
window.document.documentElement.setAttribute('lang', locale);
|
||||
|
||||
// Load the loader and start loading the workbench
|
||||
const rootUrl = uriFromPath(configuration.appRoot) + '/out';
|
||||
|
||||
// In the bundled version the nls plugin is packaged with the loader so the NLS Plugins
|
||||
// loads as soon as the loader loads. To be able to have pseudo translation
|
||||
createScript(rootUrl + '/vs/loader.js', function () {
|
||||
var define = global.define;
|
||||
global.define = undefined;
|
||||
define('fs', ['original-fs'], function (originalFS) { return originalFS; }); // replace the patched electron fs with the original node fs for all AMD code
|
||||
|
||||
window.MonacoEnvironment = {};
|
||||
|
||||
require.config({
|
||||
baseUrl: rootUrl,
|
||||
'vs/nls': nlsConfig,
|
||||
nodeCachedDataDir: configuration.nodeCachedDataDir,
|
||||
nodeModules: [/*BUILD->INSERT_NODE_MODULES*/]
|
||||
});
|
||||
|
||||
if (nlsConfig.pseudo) {
|
||||
require(['vs/nls'], function (nlsPlugin) {
|
||||
nlsPlugin.setPseudoTranslation(nlsConfig.pseudo);
|
||||
});
|
||||
}
|
||||
|
||||
require(['vs/code/electron-browser/sharedProcess/sharedProcessMain'], function (sharedProcess) {
|
||||
sharedProcess.startup({
|
||||
machineId: configuration.machineId
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
});
|
||||
@@ -3,20 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import product from 'vs/platform/node/product';
|
||||
import pkg from 'vs/platform/node/package';
|
||||
import { serve, Server, connect } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
|
||||
import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/node/extensionManagementIpc';
|
||||
import { IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
|
||||
@@ -27,22 +24,26 @@ import { RequestService } from 'vs/platform/request/electron-browser/requestServ
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { combinedAppender, NullTelemetryService, ITelemetryAppender, NullAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
|
||||
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc';
|
||||
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
|
||||
import { IWindowsService, ActiveWindowManager } from 'vs/platform/windows/common/windows';
|
||||
import { WindowsChannelClient } from 'vs/platform/windows/common/windowsIpc';
|
||||
import { WindowsChannelClient } from 'vs/platform/windows/node/windowsIpc';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { createSharedProcessContributions } from 'vs/code/electron-browser/sharedProcess/contrib/contributions';
|
||||
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
|
||||
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc';
|
||||
import { LogLevelSetterChannelClient, FollowerLogService } from 'vs/platform/log/node/logIpc';
|
||||
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
|
||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
import { LocalizationsChannel } from 'vs/platform/localizations/common/localizationsIpc';
|
||||
import { DialogChannelClient } from 'vs/platform/dialogs/common/dialogIpc';
|
||||
import { LocalizationsChannel } from 'vs/platform/localizations/node/localizationsIpc';
|
||||
import { DialogChannelClient } from 'vs/platform/dialogs/node/dialogIpc';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { DownloadService } from 'vs/platform/download/node/downloadService';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { StaticRouter } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { DefaultURITransformer } from 'vs/base/common/uriIpc';
|
||||
|
||||
export interface ISharedProcessConfiguration {
|
||||
readonly machineId: string;
|
||||
@@ -62,12 +63,19 @@ const eventPrefix = 'monacoworkbench';
|
||||
|
||||
function main(server: Server, initData: ISharedProcessInitData, configuration: ISharedProcessConfiguration): void {
|
||||
const services = new ServiceCollection();
|
||||
|
||||
const disposables: IDisposable[] = [];
|
||||
process.once('exit', () => dispose(disposables));
|
||||
|
||||
const onExit = () => dispose(disposables);
|
||||
process.once('exit', onExit);
|
||||
ipcRenderer.once('handshake:goodbye', onExit);
|
||||
|
||||
disposables.push(server);
|
||||
|
||||
const environmentService = new EnvironmentService(initData.args, process.execPath);
|
||||
const mainRoute = () => TPromise.as('main');
|
||||
const logLevelClient = new LogLevelSetterChannelClient(server.getChannel('loglevel', { routeCall: mainRoute, routeEvent: mainRoute }));
|
||||
|
||||
const mainRouter = new StaticRouter(ctx => ctx === 'main');
|
||||
const logLevelClient = new LogLevelSetterChannelClient(server.getChannel('loglevel', mainRouter));
|
||||
const logService = new FollowerLogService(logLevelClient, createSpdLogService('sharedprocess', initData.logLevel, environmentService.logsPath));
|
||||
disposables.push(logService);
|
||||
|
||||
@@ -77,14 +85,15 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I
|
||||
services.set(ILogService, logService);
|
||||
services.set(IConfigurationService, new SyncDescriptor(ConfigurationService));
|
||||
services.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
services.set(IDownloadService, new SyncDescriptor(DownloadService));
|
||||
|
||||
const windowsChannel = server.getChannel('windows', { routeCall: mainRoute, routeEvent: mainRoute });
|
||||
const windowsChannel = server.getChannel('windows', mainRouter);
|
||||
const windowsService = new WindowsChannelClient(windowsChannel);
|
||||
services.set(IWindowsService, windowsService);
|
||||
|
||||
const activeWindowManager = new ActiveWindowManager(windowsService);
|
||||
const route = () => activeWindowManager.getActiveClientId();
|
||||
const dialogChannel = server.getChannel('dialog', { routeCall: route, routeEvent: route });
|
||||
const activeWindowRouter = new StaticRouter(ctx => activeWindowManager.getActiveClientId().then(id => ctx === id));
|
||||
const dialogChannel = server.getChannel('dialog', activeWindowRouter);
|
||||
services.set(IDialogService, new DialogChannelClient(dialogChannel));
|
||||
|
||||
const instantiationService = new InstantiationService(services);
|
||||
@@ -92,27 +101,28 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I
|
||||
instantiationService.invokeFunction(accessor => {
|
||||
const services = new ServiceCollection();
|
||||
const environmentService = accessor.get(IEnvironmentService);
|
||||
const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt, installSourcePath } = environmentService;
|
||||
const { appRoot, extensionsPath, extensionDevelopmentLocationURI, isBuilt, installSourcePath } = environmentService;
|
||||
const telemetryLogService = new FollowerLogService(logLevelClient, createSpdLogService('telemetry', initData.logLevel, environmentService.logsPath));
|
||||
telemetryLogService.info('The below are logs for every telemetry event sent from VS Code once the log level is set to trace.');
|
||||
telemetryLogService.info('===========================================================');
|
||||
|
||||
let appInsightsAppender: ITelemetryAppender = NullAppender;
|
||||
if (product.aiConfig && product.aiConfig.asimovKey && isBuilt) {
|
||||
appInsightsAppender = new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey, telemetryLogService);
|
||||
disposables.push(appInsightsAppender); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
}
|
||||
server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appInsightsAppender));
|
||||
|
||||
if (!extensionDevelopmentPath && !environmentService.args['disable-telemetry'] && product.enableTelemetry) {
|
||||
let appInsightsAppender: ITelemetryAppender | null = NullAppender;
|
||||
if (!extensionDevelopmentLocationURI && !environmentService.args['disable-telemetry'] && product.enableTelemetry) {
|
||||
if (product.aiConfig && product.aiConfig.asimovKey && isBuilt) {
|
||||
appInsightsAppender = new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey, telemetryLogService);
|
||||
disposables.push(appInsightsAppender); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
}
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appender: combinedAppender(appInsightsAppender, new LogAppender(logService)),
|
||||
commonProperties: resolveCommonProperties(product.commit, pkg.version, configuration.machineId, installSourcePath),
|
||||
piiPaths: [appRoot, extensionsPath]
|
||||
};
|
||||
|
||||
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config));
|
||||
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, [config]));
|
||||
} else {
|
||||
services.set(ITelemetryService, NullTelemetryService);
|
||||
}
|
||||
server.registerChannel('telemetryAppender', new TelemetryAppenderChannel(appInsightsAppender));
|
||||
|
||||
services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
|
||||
services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
|
||||
@@ -121,8 +131,9 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I
|
||||
const instantiationService2 = instantiationService.createChild(services);
|
||||
|
||||
instantiationService2.invokeFunction(accessor => {
|
||||
|
||||
const extensionManagementService = accessor.get(IExtensionManagementService);
|
||||
const channel = new ExtensionManagementChannel(extensionManagementService);
|
||||
const channel = new ExtensionManagementChannel(extensionManagementService, () => DefaultURITransformer);
|
||||
server.registerChannel('extensions', channel);
|
||||
|
||||
// clean up deprecated extensions
|
||||
@@ -138,11 +149,11 @@ function main(server: Server, initData: ISharedProcessInitData, configuration: I
|
||||
});
|
||||
}
|
||||
|
||||
function setupIPC(hook: string): TPromise<Server> {
|
||||
function setup(retry: boolean): TPromise<Server> {
|
||||
function setupIPC(hook: string): Thenable<Server> {
|
||||
function setup(retry: boolean): Thenable<Server> {
|
||||
return serve(hook).then(null, err => {
|
||||
if (!retry || platform.isWindows || err.code !== 'EADDRINUSE') {
|
||||
return TPromise.wrapError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
|
||||
// should retry, not windows and eaddrinuse
|
||||
@@ -151,7 +162,7 @@ function setupIPC(hook: string): TPromise<Server> {
|
||||
client => {
|
||||
// we could connect to a running instance. this is not good, abort
|
||||
client.dispose();
|
||||
return TPromise.wrapError(new Error('There is an instance already running.'));
|
||||
return Promise.reject(new Error('There is an instance already running.'));
|
||||
},
|
||||
err => {
|
||||
// it happens on Linux and OS X that the pipe is left behind
|
||||
@@ -160,7 +171,7 @@ function setupIPC(hook: string): TPromise<Server> {
|
||||
try {
|
||||
fs.unlinkSync(hook);
|
||||
} catch (e) {
|
||||
return TPromise.wrapError(new Error('Error deleting the shared ipc hook.'));
|
||||
return Promise.reject(new Error('Error deleting the shared ipc hook.'));
|
||||
}
|
||||
|
||||
return setup(false);
|
||||
@@ -172,15 +183,14 @@ function setupIPC(hook: string): TPromise<Server> {
|
||||
return setup(true);
|
||||
}
|
||||
|
||||
function startHandshake(): TPromise<ISharedProcessInitData> {
|
||||
return new TPromise<ISharedProcessInitData>((c, e) => {
|
||||
async function handshake(configuration: ISharedProcessConfiguration): Promise<void> {
|
||||
const data = await new Promise<ISharedProcessInitData>(c => {
|
||||
ipcRenderer.once('handshake:hey there', (_: any, r: ISharedProcessInitData) => c(r));
|
||||
ipcRenderer.send('handshake:hello');
|
||||
});
|
||||
}
|
||||
|
||||
function handshake(configuration: ISharedProcessConfiguration): TPromise<void> {
|
||||
return startHandshake()
|
||||
.then(data => setupIPC(data.sharedIPCHandle).then(server => main(server, data, configuration)))
|
||||
.then(() => ipcRenderer.send('handshake:im ready'));
|
||||
}
|
||||
const server = await setupIPC(data.sharedIPCHandle);
|
||||
|
||||
main(server, data, configuration);
|
||||
ipcRenderer.send('handshake:im ready');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user