From 70d47c17577bc40c1ec52623b5c5b83abd4dd29f Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Thu, 23 Aug 2018 15:33:23 -0400 Subject: [PATCH] Prompt to create Profiler session per server (#2303) * Null check getXEventSessions return value * Profiler state WIP * Fix various bugs getting session state --- .../parts/profiler/editor/profilerEditor.ts | 37 +++++++++++--- src/sql/parts/profiler/service/interfaces.ts | 6 +++ .../parts/profiler/service/profilerService.ts | 49 +++++++++++++++++-- 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/src/sql/parts/profiler/editor/profilerEditor.ts b/src/sql/parts/profiler/editor/profilerEditor.ts index b9ed8380af..457ce69fdd 100644 --- a/src/sql/parts/profiler/editor/profilerEditor.ts +++ b/src/sql/parts/profiler/editor/profilerEditor.ts @@ -17,7 +17,6 @@ import * as Actions from 'sql/parts/profiler/contrib/profilerActions'; import { CONTEXT_PROFILER_EDITOR, PROFILER_TABLE_COMMAND_SEARCH } from './interfaces'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox'; import { textFormatter } from 'sql/parts/grid/services/sharedServices'; - import * as DOM from 'vs/base/browser/dom'; import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { TPromise } from 'vs/base/common/winjs.base'; @@ -99,7 +98,8 @@ export interface IDetailData { } export class ProfilerEditor extends BaseEditor { - public static ID: string = 'workbench.editor.profiler'; + public static readonly ID: string = 'workbench.editor.profiler'; + private _editor: ProfilerResourceEditor; private _editorModel: ITextModel; private _editorInput: UntitledEditorInput; @@ -158,9 +158,6 @@ export class ProfilerEditor extends BaseEditor { } protected createEditor(parent: HTMLElement): void { - // test backend - //this._profilerService.registerProvider('default', this._instantiationService.createInstance(ProfilerTestBackend)); - this._container = document.createElement('div'); this._container.className = 'carbon-profiler'; parent.appendChild(this._container); @@ -457,13 +454,32 @@ export class ProfilerEditor extends BaseEditor { this._connectAction.connected = this.input.state.isConnected; if (this.input.state.isConnected) { + this._updateToolbar(); this._sessionSelector.enable(); this._profilerService.getXEventSessions(this.input.id).then((r) => { + // set undefined result to empty list + if (!r) { + r = []; + } + this._sessionSelector.setOptions(r); this._sessionsList = r; - if (this.input.sessionName === undefined || this.input.sessionName === '') { - this.input.sessionName = this._sessionsList[0]; + if ((this.input.sessionName === undefined || this.input.sessionName === '') && this._sessionsList.length > 0) { + let sessionIndex: number = 0; + let uiState = this._profilerService.getSessionViewState(this.input.id); + if (uiState && uiState.previousSessionName) { + sessionIndex = this._sessionsList.indexOf(uiState.previousSessionName); + } else { + this._profilerService.launchCreateSessionDialog(this.input); + } + + if (sessionIndex < 0) { + sessionIndex = 0; + } + + this.input.sessionName = this._sessionsList[sessionIndex]; + this._sessionSelector.selectWithOptionName(this.input.sessionName); } }); } else { @@ -493,9 +509,14 @@ export class ProfilerEditor extends BaseEditor { this._updateToolbar(); this._sessionSelector.enable(); this._profilerService.getXEventSessions(this.input.id).then((r) => { + // set undefined result to empty list + if (!r) { + r = []; + } + this._sessionsList = r; this._sessionSelector.setOptions(r); - if (this.input.sessionName === undefined || this.input.sessionName === '') { + if ((this.input.sessionName === undefined || this.input.sessionName === '') && this._sessionsList.length > 0) { this.input.sessionName = this._sessionsList[0]; } }); diff --git a/src/sql/parts/profiler/service/interfaces.ts b/src/sql/parts/profiler/service/interfaces.ts index bdcf8c636b..225531004c 100644 --- a/src/sql/parts/profiler/service/interfaces.ts +++ b/src/sql/parts/profiler/service/interfaces.ts @@ -109,6 +109,12 @@ export interface IProfilerService { * otherwise returns all session templates */ getSessionTemplates(providerId?: string): Array; + /** + * Gets the session view state + * @param sessionId The session ID to get the view state for + * @returns Sessions view state + */ + getSessionViewState(sessionId: string): any; /** * Launches the dialog for editing the view columns of a profiler session template for the given input * @param input input object that contains the necessary information which will be modified based on used input diff --git a/src/sql/parts/profiler/service/profilerService.ts b/src/sql/parts/profiler/service/profilerService.ts index 98899ee5a8..6fd36b7ae8 100644 --- a/src/sql/parts/profiler/service/profilerService.ts +++ b/src/sql/parts/profiler/service/profilerService.ts @@ -19,6 +19,8 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { ICommandService } from 'vs/platform/commands/common/commands'; +import { IStorageService } from 'vs/platform/storage/common/storage'; +import { Scope as MementoScope, Memento } from 'vs/workbench/common/memento'; class TwoWayMap { private forwardMap: Map; @@ -45,19 +47,27 @@ class TwoWayMap { } export class ProfilerService implements IProfilerService { + private static readonly PROFILER_SERVICE_UI_STATE_STORAGE_KEY = 'profileservice.uiState'; public _serviceBrand: any; private _providers = new Map(); private _idMap = new TwoWayMap(); private _sessionMap = new Map(); + private _connectionMap = new Map(); private _editColumnDialog: ProfilerColumnEditorDialog; + private _memento: any; + private _context: Memento; constructor( @IConnectionManagementService private _connectionService: IConnectionManagementService, @IConfigurationService public _configurationService: IConfigurationService, @IInstantiationService private _instantiationService: IInstantiationService, @INotificationService private _notificationService: INotificationService, - @ICommandService private _commandService: ICommandService - ) { } + @ICommandService private _commandService: ICommandService, + @IStorageService private _storageService: IStorageService + ) { + this._context = new Memento('ProfilerEditor'); + this._memento = this._context.getMemento(this._storageService, MementoScope.GLOBAL); + } public registerProvider(providerId: string, provider: sqlops.ProfilerProvider): void { this._providers.set(providerId, provider); @@ -77,23 +87,22 @@ export class ProfilerService implements IProfilerService { } this._sessionMap.set(uri, session); + this._connectionMap.set(uri, connectionProfile); this._idMap.set(uri, uri); return TPromise.wrap(uri); } public onMoreRows(params: sqlops.ProfilerSessionEvents): void { - this._sessionMap.get(this._idMap.reverseGet(params.sessionId)).onMoreRows(params); } public onSessionStopped(params: sqlops.ProfilerSessionStoppedParams): void { - this._sessionMap.get(this._idMap.reverseGet(params.ownerUri)).onSessionStopped(params); } public onProfilerSessionCreated(params: sqlops.ProfilerSessionCreatedParams): void { - this._sessionMap.get(this._idMap.reverseGet(params.ownerUri)).onProfilerSessionCreated(params); + this.updateMemento(params.ownerUri, { previousSessionName: params.sessionName }); } public connectSession(id: ProfilerSessionID): Thenable { @@ -114,6 +123,7 @@ export class ProfilerService implements IProfilerService { } public startSession(id: ProfilerSessionID, sessionName: string): Thenable { + this.updateMemento(id, { previousSessionName: sessionName }); return this._runAction(id, provider => provider.startSession(this._idMap.get(id), sessionName)).then(() => { this._sessionMap.get(this._idMap.reverseGet(id)).onSessionStateChanged({ isRunning: true, isStopped: false, isPaused: false }); return true; @@ -178,6 +188,35 @@ export class ProfilerService implements IProfilerService { } } + public getSessionViewState(ownerUri: string): any { + let mementoKey = this.getMementoKey(ownerUri); + let uiStateMap = this._memento[ProfilerService.PROFILER_SERVICE_UI_STATE_STORAGE_KEY]; + if (uiStateMap && mementoKey) { + return uiStateMap[mementoKey]; + } + return undefined; + } + + private getMementoKey(ownerUri: string): string { + let mementoKey = undefined; + let connectionProfile: IConnectionProfile = this._connectionMap.get(ownerUri); + if (connectionProfile) { + mementoKey = connectionProfile.serverName; + } + return mementoKey; + } + + private updateMemento(ownerUri: string, uiState: any) { + // update persisted session state + let mementoKey = this.getMementoKey(ownerUri); + let uiStateMap = this._memento[ProfilerService.PROFILER_SERVICE_UI_STATE_STORAGE_KEY]; + if (uiStateMap && mementoKey) { + uiStateMap[mementoKey] = uiState; + this._memento[ProfilerService.PROFILER_SERVICE_UI_STATE_STORAGE_KEY] = uiStateMap; + this._context.saveMemento(); + } + } + public launchColumnEditor(input?: ProfilerInput): Thenable { if (!this._editColumnDialog) { this._editColumnDialog = this._instantiationService.createInstance(ProfilerColumnEditorDialog);