mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from master
This commit is contained in:
@@ -3,14 +3,12 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import 'vs/css!./media/shell';
|
||||
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as perf from 'vs/base/common/performance';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import product from 'vs/platform/node/product';
|
||||
@@ -19,8 +17,8 @@ import pkg from 'vs/platform/node/package';
|
||||
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
|
||||
import { Workbench, IWorkbenchStartedInfo } from 'vs/workbench/electron-browser/workbench';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService, configurationTelemetry, LogAppender, combinedAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
|
||||
import { NullTelemetryService, configurationTelemetry, combinedAppender, LogAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
|
||||
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
|
||||
@@ -42,11 +40,10 @@ import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
|
||||
import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { ILifecycleService, LifecyclePhase, ShutdownReason, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/node/instantiationService';
|
||||
import { ILifecycleService, LifecyclePhase, WillShutdownEvent } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ISearchService, ISearchHistoryService } from 'vs/platform/search/common/search';
|
||||
@@ -58,19 +55,17 @@ import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/work
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { ICrashReporterService, NullCrashReporterService, CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService';
|
||||
import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { getDelayedChannel, IPCClient } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { DefaultURITransformer } from 'vs/base/common/uriIpc';
|
||||
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
|
||||
import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/node/extensionManagementIpc';
|
||||
import { IExtensionManagementService, IExtensionEnablementService, IExtensionManagementServerService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
|
||||
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
|
||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||
import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { ITextResourceConfigurationService, ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl';
|
||||
import { registerThemingParticipant, ITheme, ICssStyleCollector, HIGH_CONTRAST } from 'vs/platform/theme/common/themeService';
|
||||
import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
@@ -80,10 +75,11 @@ import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/elect
|
||||
import { HashService } from 'vs/workbench/services/hash/node/hashService';
|
||||
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { DelegatingStorageService } from 'vs/platform/storage/node/storageService';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { WORKBENCH_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { stat } from 'fs';
|
||||
import { join } from 'path';
|
||||
import { ILocalizationsChannel, LocalizationsChannelClient } from 'vs/platform/localizations/common/localizationsIpc';
|
||||
import { LocalizationsChannelClient } from 'vs/platform/localizations/node/localizationsIpc';
|
||||
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue';
|
||||
import { WorkbenchIssueService } from 'vs/workbench/services/issue/electron-browser/workbenchIssueService';
|
||||
@@ -91,13 +87,24 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
import { NotificationService } from 'vs/workbench/services/notification/common/notificationService';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { DialogService } from 'vs/workbench/services/dialogs/electron-browser/dialogService';
|
||||
import { DialogChannel } from 'vs/platform/dialogs/common/dialogIpc';
|
||||
import { EventType, addDisposableListener, addClass } from 'vs/base/browser/dom';
|
||||
import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc';
|
||||
import { EventType, addDisposableListener, addClass, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/node/remoteAgentService';
|
||||
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { OpenerService } from 'vs/editor/browser/services/openerService';
|
||||
import { SearchHistoryService } from 'vs/workbench/services/search/node/searchHistoryService';
|
||||
import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/common/multiExtensionManagement';
|
||||
import { ExtensionManagementServerService } from 'vs/workbench/services/extensions/node/extensionManagementServerService';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
|
||||
import { LogLevelSetterChannel } from 'vs/platform/log/node/logIpc';
|
||||
import { ILabelService, LabelService } from 'vs/platform/label/common/label';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { DownloadService } from 'vs/platform/download/node/downloadService';
|
||||
import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc';
|
||||
import { TextResourcePropertiesService } from 'vs/workbench/services/textfile/electron-browser/textResourcePropertiesService';
|
||||
import { MulitExtensionManagementService } from 'vs/platform/extensionManagement/node/multiExtensionManagement';
|
||||
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { RemoteAuthorityResolverService } from 'vs/platform/remote/electron-browser/remoteAuthorityResolverService';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { FileTelemetryService } from 'sql/workbench/services/telemetry/node/fileTelemetryService';
|
||||
@@ -110,8 +117,7 @@ export interface ICoreServices {
|
||||
configurationService: IConfigurationService;
|
||||
environmentService: IEnvironmentService;
|
||||
logService: ILogService;
|
||||
timerService: ITimerService;
|
||||
storageService: IStorageService;
|
||||
storageService: DelegatingStorageService;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,15 +125,17 @@ export interface ICoreServices {
|
||||
* With the Shell being the top level element in the page, it is also responsible for driving the layouting.
|
||||
*/
|
||||
export class WorkbenchShell extends Disposable {
|
||||
private storageService: IStorageService;
|
||||
|
||||
private readonly _onWillShutdown = this._register(new Emitter<WillShutdownEvent>());
|
||||
get onWillShutdown(): Event<WillShutdownEvent> { return this._onWillShutdown.event; }
|
||||
|
||||
private storageService: DelegatingStorageService;
|
||||
private environmentService: IEnvironmentService;
|
||||
private logService: ILogService;
|
||||
private configurationService: IConfigurationService;
|
||||
private contextService: IWorkspaceContextService;
|
||||
private telemetryService: ITelemetryService;
|
||||
private extensionService: ExtensionService;
|
||||
private broadcastService: IBroadcastService;
|
||||
private timerService: ITimerService;
|
||||
private themeService: WorkbenchThemeService;
|
||||
private lifecycleService: LifecycleService;
|
||||
private mainProcessServices: ServiceCollection;
|
||||
@@ -151,7 +159,6 @@ export class WorkbenchShell extends Disposable {
|
||||
this.configurationService = coreServices.configurationService;
|
||||
this.environmentService = coreServices.environmentService;
|
||||
this.logService = coreServices.logService;
|
||||
this.timerService = coreServices.timerService;
|
||||
this.storageService = coreServices.storageService;
|
||||
|
||||
this.mainProcessServices = mainProcessServices;
|
||||
@@ -160,12 +167,20 @@ export class WorkbenchShell extends Disposable {
|
||||
}
|
||||
|
||||
private renderContents(): void {
|
||||
|
||||
// ARIA
|
||||
aria.setARIAContainer(document.body);
|
||||
|
||||
// Instantiation service with services
|
||||
const [instantiationService, serviceCollection] = this.initServiceCollection(this.container);
|
||||
|
||||
// Warm up font cache information before building up too many dom elements
|
||||
restoreFontInfo(this.storageService);
|
||||
readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), browser.getZoomLevel()));
|
||||
this._register(this.storageService.onWillSaveState(() => {
|
||||
saveFontInfo(this.storageService); // Keep font info for next startup around
|
||||
}));
|
||||
|
||||
// Workbench
|
||||
this.workbench = this.createWorkbench(instantiationService, serviceCollection, this.container);
|
||||
|
||||
@@ -177,53 +192,42 @@ export class WorkbenchShell extends Disposable {
|
||||
this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
|
||||
}, 10000);
|
||||
|
||||
this.lifecycleService.when(LifecyclePhase.Running).then(() => {
|
||||
this.lifecycleService.when(LifecyclePhase.Restored).then(() => {
|
||||
clearTimeout(timeoutHandle);
|
||||
});
|
||||
}
|
||||
|
||||
private createWorkbench(instantiationService: IInstantiationService, serviceCollection: ServiceCollection, container: HTMLElement): Workbench {
|
||||
|
||||
function handleStartupError(logService: ILogService, error: Error): void {
|
||||
|
||||
// Log it
|
||||
logService.error(toErrorMessage(error, true));
|
||||
|
||||
// Rethrow
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
const workbench = instantiationService.createInstance(Workbench, container, this.configuration, serviceCollection, this.lifecycleService, this.mainProcessClient);
|
||||
|
||||
// Set lifecycle phase to `Restoring`
|
||||
this.lifecycleService.phase = LifecyclePhase.Restoring;
|
||||
|
||||
// Startup Workbench
|
||||
workbench.startup().done(startupInfos => {
|
||||
|
||||
// Set lifecycle phase to `Runnning` so that other contributions can now do something
|
||||
this.lifecycleService.phase = LifecyclePhase.Running;
|
||||
workbench.startup().then(startupInfos => {
|
||||
|
||||
// Startup Telemetry
|
||||
this.logStartupTelemetry(startupInfos);
|
||||
|
||||
// Set lifecycle phase to `Runnning For A Bit` after a short delay
|
||||
let eventuallPhaseTimeoutHandle = setTimeout(() => {
|
||||
eventuallPhaseTimeoutHandle = void 0;
|
||||
this.lifecycleService.phase = LifecyclePhase.Eventually;
|
||||
}, 3000);
|
||||
|
||||
this._register(toDisposable(() => {
|
||||
if (eventuallPhaseTimeoutHandle) {
|
||||
clearTimeout(eventuallPhaseTimeoutHandle);
|
||||
}
|
||||
}));
|
||||
|
||||
// localStorage metrics (TODO@Ben remove me later)
|
||||
if (!this.environmentService.extensionTestsPath && this.contextService.getWorkbenchState() === WorkbenchState.FOLDER) {
|
||||
this.logLocalStorageMetrics();
|
||||
// Storage Telemetry (TODO@Ben remove me later, including storage errors)
|
||||
if (!this.environmentService.extensionTestsPath) {
|
||||
this.logStorageTelemetry();
|
||||
}
|
||||
});
|
||||
}, error => handleStartupError(this.logService, error));
|
||||
|
||||
return workbench;
|
||||
} catch (error) {
|
||||
handleStartupError(this.logService, error);
|
||||
|
||||
// Log it
|
||||
this.logService.error(toErrorMessage(error, true));
|
||||
|
||||
// Rethrow
|
||||
throw error;
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,9 +276,9 @@ export class WorkbenchShell extends Disposable {
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
private sendUsageEvents(): void {
|
||||
const dailyLastUseDate = Date.parse(this.storageService.get('telemetry.dailyLastUseDate'));
|
||||
const weeklyLastUseDate = Date.parse(this.storageService.get('telemetry.weeklyLastUseDate'));
|
||||
const monthlyLastUseDate = Date.parse(this.storageService.get('telemetry.monthlyLastUseDate'));
|
||||
const dailyLastUseDate = Date.parse(this.storageService.get('telemetry.dailyLastUseDate', StorageScope.GLOBAL, '0'));
|
||||
const weeklyLastUseDate = Date.parse(this.storageService.get('telemetry.weeklyLastUseDate', StorageScope.GLOBAL, '0'));
|
||||
const monthlyLastUseDate = Date.parse(this.storageService.get('telemetry.monthlyLastUseDate', StorageScope.GLOBAL, '0'));
|
||||
|
||||
let today = new Date().toUTCString();
|
||||
|
||||
@@ -282,68 +286,124 @@ export class WorkbenchShell extends Disposable {
|
||||
if (this.diffInDays(Date.parse(today), dailyLastUseDate) >= 1) {
|
||||
// daily first use
|
||||
this.telemetryService.publicLog('telemetry.dailyFirstUse', { dailyFirstUse: true });
|
||||
this.storageService.store('telemetry.dailyLastUseDate', today);
|
||||
this.storageService.store('telemetry.dailyLastUseDate', today, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
// weekly user event
|
||||
if (this.diffInDays(Date.parse(today), weeklyLastUseDate) >= 7) {
|
||||
// weekly first use
|
||||
this.telemetryService.publicLog('telemetry.weeklyFirstUse', { weeklyFirstUse: true });
|
||||
this.storageService.store('telemetry.weeklyLastUseDate', today);
|
||||
this.storageService.store('telemetry.weeklyLastUseDate', today, StorageScope.GLOBAL);
|
||||
}
|
||||
|
||||
// monthly user events
|
||||
if (this.diffInDays(Date.parse(today), monthlyLastUseDate) >= 30) {
|
||||
this.telemetryService.publicLog('telemetry.monthlyUse', { monthlyFirstUse: true });
|
||||
this.storageService.store('telemetry.monthlyLastUseDate', today);
|
||||
this.storageService.store('telemetry.monthlyLastUseDate', today, StorageScope.GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
private logLocalStorageMetrics(): void {
|
||||
if (this.lifecycleService.startupKind === StartupKind.ReloadedWindow || this.lifecycleService.startupKind === StartupKind.ReopenedWindow) {
|
||||
return; // avoid logging localStorage metrics for reload/reopen, we prefer cold startup numbers
|
||||
}
|
||||
private logStorageTelemetry(): void {
|
||||
const initialStartup = !!this.configuration.isInitialStartup;
|
||||
|
||||
perf.mark('willReadLocalStorage');
|
||||
const readyToSend = this.storageService.getBoolean('localStorageMetricsReadyToSend2');
|
||||
perf.mark('didReadLocalStorage');
|
||||
const appReadyDuration = initialStartup ? perf.getDuration('main:started', 'main:appReady') : 0;
|
||||
const workbenchReadyDuration = perf.getDuration(initialStartup ? 'main:started' : 'main:loadWindow', 'didStartWorkbench');
|
||||
const workspaceStorageRequireDuration = perf.getDuration('willRequireSQLite', 'didRequireSQLite');
|
||||
const workspaceStorageSchemaDuration = perf.getDuration('willSetupSQLiteSchema', 'didSetupSQLiteSchema');
|
||||
const globalStorageInitDurationMain = perf.getDuration('main:willInitGlobalStorage', 'main:didInitGlobalStorage');
|
||||
const globalStorageInitDuratioRenderer = perf.getDuration('willInitGlobalStorage', 'didInitGlobalStorage');
|
||||
const workspaceStorageInitDuration = perf.getDuration('willInitWorkspaceStorage', 'didInitWorkspaceStorage');
|
||||
const workspaceStorageFileExistsDuration = perf.getDuration('willCheckWorkspaceStorageExists', 'didCheckWorkspaceStorageExists');
|
||||
const workspaceStorageMigrationDuration = perf.getDuration('willMigrateWorkspaceStorageKeys', 'didMigrateWorkspaceStorageKeys');
|
||||
const workbenchLoadDuration = perf.getDuration('willLoadWorkbenchMain', 'didLoadWorkbenchMain');
|
||||
const localStorageDuration = perf.getDuration('willReadLocalStorage', 'didReadLocalStorage');
|
||||
|
||||
if (!readyToSend) {
|
||||
this.storageService.store('localStorageMetricsReadyToSend2', true);
|
||||
return; // avoid logging localStorage metrics directly after the update, we prefer cold startup numbers
|
||||
}
|
||||
// Handle errors (avoid duplicates to reduce spam)
|
||||
const loggedStorageErrors = new Set<string>();
|
||||
this._register(this.storageService.storage.onWorkspaceStorageError(error => {
|
||||
const errorStr = `${error}`;
|
||||
|
||||
if (!this.storageService.getBoolean('localStorageMetricsSent2')) {
|
||||
perf.mark('willWriteLocalStorage');
|
||||
this.storageService.store('localStorageMetricsSent2', true);
|
||||
perf.mark('didWriteLocalStorage');
|
||||
|
||||
perf.mark('willStatLocalStorage');
|
||||
stat(join(this.environmentService.userDataPath, 'Local Storage', 'file__0.localstorage'), (error, stat) => {
|
||||
perf.mark('didStatLocalStorage');
|
||||
if (!loggedStorageErrors.has(errorStr)) {
|
||||
loggedStorageErrors.add(errorStr);
|
||||
|
||||
/* __GDPR__
|
||||
"localStorageTimers<NUMBER>" : {
|
||||
"statTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"accessTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"firstReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"subsequentReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"writeTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"keys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"size": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
"sqliteStorageError<NUMBER>" : {
|
||||
"appReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbenchReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceExistsTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceMigrationTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceSchemaTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"globalReadTimeMain" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"globalReadTimeRenderer" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"localStorageTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbenchRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceKeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"storageError": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('localStorageTimers2', {
|
||||
'statTime': perf.getDuration('willStatLocalStorage', 'didStatLocalStorage'),
|
||||
'accessTime': perf.getDuration('willAccessLocalStorage', 'didAccessLocalStorage'),
|
||||
'firstReadTime': perf.getDuration('willReadWorkspaceIdentifier', 'didReadWorkspaceIdentifier'),
|
||||
'subsequentReadTime': perf.getDuration('willReadLocalStorage', 'didReadLocalStorage'),
|
||||
'writeTime': perf.getDuration('willWriteLocalStorage', 'didWriteLocalStorage'),
|
||||
'keys': window.localStorage.length,
|
||||
'size': stat ? stat.size : -1
|
||||
this.telemetryService.publicLog('sqliteStorageError5', {
|
||||
'appReadyTime': appReadyDuration,
|
||||
'workbenchReadyTime': workbenchReadyDuration,
|
||||
'workspaceExistsTime': workspaceStorageFileExistsDuration,
|
||||
'workspaceMigrationTime': workspaceStorageMigrationDuration,
|
||||
'workspaceRequireTime': workspaceStorageRequireDuration,
|
||||
'workspaceSchemaTime': workspaceStorageSchemaDuration,
|
||||
'globalReadTimeMain': globalStorageInitDurationMain,
|
||||
'globalReadTimeRenderer': globalStorageInitDuratioRenderer,
|
||||
'workspaceReadTime': workspaceStorageInitDuration,
|
||||
'localStorageTime': localStorageDuration,
|
||||
'workbenchRequireTime': workbenchLoadDuration,
|
||||
'workspaceKeys': this.storageService.storage.getSize(StorageScope.WORKSPACE),
|
||||
'startupKind': this.lifecycleService.startupKind,
|
||||
'storageError': errorStr
|
||||
});
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
if (this.storageService.storage.hasErrors) {
|
||||
return; // do not log performance numbers when errors occured
|
||||
}
|
||||
|
||||
if (this.environmentService.verbose) {
|
||||
return; // do not log when running in verbose mode
|
||||
}
|
||||
|
||||
/* __GDPR__
|
||||
"sqliteStorageTimers<NUMBER>" : {
|
||||
"appReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbenchReadyTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceExistsTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceMigrationTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceSchemaTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"globalReadTimeMain" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"globalReadTimeRenderer" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceReadTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"localStorageTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workbenchRequireTime" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"workspaceKeys" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
|
||||
}
|
||||
*/
|
||||
this.telemetryService.publicLog('sqliteStorageTimers5', {
|
||||
'appReadyTime': appReadyDuration,
|
||||
'workbenchReadyTime': workbenchReadyDuration,
|
||||
'workspaceExistsTime': workspaceStorageFileExistsDuration,
|
||||
'workspaceMigrationTime': workspaceStorageMigrationDuration,
|
||||
'workspaceRequireTime': workspaceStorageRequireDuration,
|
||||
'workspaceSchemaTime': workspaceStorageSchemaDuration,
|
||||
'globalReadTimeMain': globalStorageInitDurationMain,
|
||||
'globalReadTimeRenderer': globalStorageInitDuratioRenderer,
|
||||
'workspaceReadTime': workspaceStorageInitDuration,
|
||||
'localStorageTime': localStorageDuration,
|
||||
'workbenchRequireTime': workbenchLoadDuration,
|
||||
'workspaceKeys': this.storageService.storage.getSize(StorageScope.WORKSPACE),
|
||||
'startupKind': this.lifecycleService.startupKind
|
||||
});
|
||||
}
|
||||
|
||||
private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
|
||||
@@ -351,10 +411,10 @@ export class WorkbenchShell extends Disposable {
|
||||
serviceCollection.set(IWorkspaceContextService, this.contextService);
|
||||
serviceCollection.set(IConfigurationService, this.configurationService);
|
||||
serviceCollection.set(IEnvironmentService, this.environmentService);
|
||||
serviceCollection.set(ILabelService, new SyncDescriptor(LabelService));
|
||||
serviceCollection.set(ILogService, this._register(this.logService));
|
||||
|
||||
serviceCollection.set(ITimerService, this.timerService);
|
||||
serviceCollection.set(IStorageService, this.storageService);
|
||||
|
||||
this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
|
||||
serviceCollection.set(serviceIdentifier, serviceInstance);
|
||||
});
|
||||
@@ -367,17 +427,14 @@ export class WorkbenchShell extends Disposable {
|
||||
this.broadcastService = instantiationService.createInstance(BroadcastService, this.configuration.windowId);
|
||||
serviceCollection.set(IBroadcastService, this.broadcastService);
|
||||
|
||||
serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, this.configuration.windowId, this.configuration));
|
||||
serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, [this.configuration.windowId, this.configuration]));
|
||||
|
||||
const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
|
||||
.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${this.configuration.windowId}`));
|
||||
|
||||
sharedProcess
|
||||
.done(client => client.registerChannel('dialog', instantiationService.createInstance(DialogChannel)));
|
||||
|
||||
// Warm up font cache information before building up too many dom elements
|
||||
restoreFontInfo(this.storageService);
|
||||
readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), browser.getZoomLevel()));
|
||||
sharedProcess.then(client => {
|
||||
client.registerChannel('dialog', instantiationService.createInstance(DialogChannel));
|
||||
});
|
||||
|
||||
// Hash
|
||||
serviceCollection.set(IHashService, new SyncDescriptor(HashService));
|
||||
@@ -386,9 +443,9 @@ export class WorkbenchShell extends Disposable {
|
||||
if (this.environmentService.args['perf-test']) {
|
||||
let telemetryOutput = this.environmentService.args['telemetry-output'];
|
||||
this.telemetryService = new FileTelemetryService(telemetryOutput);
|
||||
// Telemetry
|
||||
} else if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
|
||||
const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
|
||||
// Telemetry
|
||||
} else if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
|
||||
const channel = getDelayedChannel(sharedProcess.then(c => c.getChannel('telemetryAppender')));
|
||||
const config: ITelemetryServiceConfig = {
|
||||
appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(this.logService)),
|
||||
commonProperties: resolveWorkbenchCommonProperties(this.storageService, product.commit, pkg.version, this.configuration.machineId, this.environmentService.installSourcePath),
|
||||
@@ -416,27 +473,37 @@ export class WorkbenchShell extends Disposable {
|
||||
serviceCollection.set(IDialogService, instantiationService.createInstance(DialogService));
|
||||
|
||||
const lifecycleService = instantiationService.createInstance(LifecycleService);
|
||||
this._register(lifecycleService.onShutdown(reason => this.dispose(reason)));
|
||||
this._register(lifecycleService.onWillShutdown(event => this._onWillShutdown.fire(event)));
|
||||
this._register(lifecycleService.onShutdown(() => this.dispose()));
|
||||
serviceCollection.set(ILifecycleService, lifecycleService);
|
||||
this.lifecycleService = lifecycleService;
|
||||
|
||||
const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions')));
|
||||
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel, DefaultURITransformer);
|
||||
serviceCollection.set(IExtensionManagementServerService, new SyncDescriptor(ExtensionManagementServerService, extensionManagementChannelClient));
|
||||
serviceCollection.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
serviceCollection.set(IDownloadService, new SyncDescriptor(DownloadService));
|
||||
serviceCollection.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));
|
||||
|
||||
const remoteAuthorityResolverService = new RemoteAuthorityResolverService();
|
||||
serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService);
|
||||
|
||||
const remoteAgentService = new RemoteAgentService(this.configuration, this.notificationService, this.environmentService, remoteAuthorityResolverService);
|
||||
serviceCollection.set(IRemoteAgentService, remoteAgentService);
|
||||
|
||||
const remoteAgentConnection = remoteAgentService.getConnection();
|
||||
if (remoteAgentConnection) {
|
||||
remoteAgentConnection.registerChannel('dialog', instantiationService.createInstance(DialogChannel));
|
||||
remoteAgentConnection.registerChannel('download', new DownloadServiceChannel());
|
||||
remoteAgentConnection.registerChannel('loglevel', new LogLevelSetterChannel(this.logService));
|
||||
}
|
||||
|
||||
const extensionManagementChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('extensions')));
|
||||
const extensionManagementChannelClient = new ExtensionManagementChannelClient(extensionManagementChannel);
|
||||
serviceCollection.set(IExtensionManagementServerService, new SyncDescriptor(ExtensionManagementServerService, [extensionManagementChannelClient]));
|
||||
serviceCollection.set(IExtensionManagementService, new SyncDescriptor(MulitExtensionManagementService));
|
||||
|
||||
const extensionEnablementService = this._register(instantiationService.createInstance(ExtensionEnablementService));
|
||||
serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
|
||||
|
||||
serviceCollection.set(IRequestService, new SyncDescriptor(RequestService));
|
||||
|
||||
this.extensionService = instantiationService.createInstance(ExtensionService);
|
||||
serviceCollection.set(IExtensionService, this.extensionService);
|
||||
|
||||
perf.mark('willLoadExtensions');
|
||||
this.extensionService.whenInstalledExtensionsRegistered().done(() => {
|
||||
perf.mark('didLoadExtensions');
|
||||
});
|
||||
serviceCollection.set(IExtensionService, instantiationService.createInstance(ExtensionService));
|
||||
|
||||
this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
|
||||
serviceCollection.set(IWorkbenchThemeService, this.themeService);
|
||||
@@ -447,10 +514,12 @@ export class WorkbenchShell extends Disposable {
|
||||
|
||||
serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
|
||||
|
||||
serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
|
||||
|
||||
serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));
|
||||
|
||||
serviceCollection.set(ITextResourcePropertiesService, new SyncDescriptor(TextResourcePropertiesService));
|
||||
|
||||
serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
|
||||
|
||||
serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
|
||||
|
||||
serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
|
||||
@@ -469,8 +538,8 @@ export class WorkbenchShell extends Disposable {
|
||||
|
||||
serviceCollection.set(IIntegrityService, new SyncDescriptor(IntegrityServiceImpl));
|
||||
|
||||
const localizationsChannel = getDelayedChannel<ILocalizationsChannel>(sharedProcess.then(c => c.getChannel('localizations')));
|
||||
serviceCollection.set(ILocalizationsService, new SyncDescriptor(LocalizationsChannelClient, localizationsChannel));
|
||||
const localizationsChannel = getDelayedChannel(sharedProcess.then(c => c.getChannel('localizations')));
|
||||
serviceCollection.set(ILocalizationsService, new SyncDescriptor(LocalizationsChannelClient, [localizationsChannel]));
|
||||
|
||||
return [instantiationService, serviceCollection];
|
||||
}
|
||||
@@ -478,9 +547,10 @@ export class WorkbenchShell extends Disposable {
|
||||
open(): void {
|
||||
|
||||
// Listen on unhandled rejection events
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
window.addEventListener('unhandledrejection', (event: PromiseRejectionEvent) => {
|
||||
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent
|
||||
errors.onUnexpectedError((<any>event).reason);
|
||||
errors.onUnexpectedError(event.reason);
|
||||
|
||||
// Prevent the printing of this event to the console
|
||||
event.preventDefault();
|
||||
@@ -502,16 +572,31 @@ export class WorkbenchShell extends Disposable {
|
||||
|
||||
// Listeners
|
||||
this.registerListeners();
|
||||
|
||||
// Set lifecycle phase to `Ready`
|
||||
this.lifecycleService.phase = LifecyclePhase.Ready;
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
this._register(addDisposableListener(window, EventType.RESIZE, e => this.onWindowResize(e, true)));
|
||||
}
|
||||
|
||||
// Resize
|
||||
this._register(addDisposableListener(window, EventType.RESIZE, e => {
|
||||
if (e.target === window) {
|
||||
this.layout();
|
||||
private onWindowResize(e: any, retry: boolean): void {
|
||||
if (e.target === window) {
|
||||
if (window.document && window.document.body && window.document.body.clientWidth === 0) {
|
||||
// TODO@Ben this is an electron issue on macOS when simple fullscreen is enabled
|
||||
// where for some reason the window clientWidth is reported as 0 when switching
|
||||
// between simple fullscreen and normal screen. In that case we schedule the layout
|
||||
// call at the next animation frame once, in the hope that the dimensions are
|
||||
// proper then.
|
||||
if (retry) {
|
||||
scheduleAtNextAnimationFrame(() => this.onWindowResize(e, false));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}));
|
||||
|
||||
this.layout();
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
@@ -546,20 +631,18 @@ export class WorkbenchShell extends Disposable {
|
||||
this.workbench.layout();
|
||||
}
|
||||
|
||||
dispose(reason = ShutdownReason.QUIT): void {
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
// Keep font info for next startup around
|
||||
saveFontInfo(this.storageService);
|
||||
|
||||
// Dispose Workbench
|
||||
if (this.workbench) {
|
||||
this.workbench.dispose(reason);
|
||||
this.workbench.dispose();
|
||||
}
|
||||
|
||||
this.mainProcessClient.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
|
||||
// Foreground
|
||||
|
||||
Reference in New Issue
Block a user