mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-19 01:25:36 -05:00
Stops second invocation of createNewSession while expanding OE tree items on disconnected servers (#21437)
* Debounces second invocation while expanding OE tree items * Minor clean up * Adjusts debounce time * Adding temp trace comments * Adds missing semicolon * Removes debouncer to stop 2nd newSession calls * Removes temp trace comments * Updates comment Co-authored-by: Alan Ren <alanren@microsoft.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import { ServerTreeActionProvider } from 'sql/workbench/services/objectExplorer/
|
||||
import { ITree } from 'sql/base/parts/tree/browser/tree';
|
||||
import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { ObjectExplorerRequestStatus } from 'sql/workbench/services/objectExplorer/browser/treeSelectionHandler';
|
||||
|
||||
export const SERVICE_ID = 'ObjectExplorerService';
|
||||
|
||||
@@ -87,7 +88,7 @@ export interface IObjectExplorerService {
|
||||
|
||||
getObjectExplorerNode(connection: IConnectionProfile): TreeNode | undefined;
|
||||
|
||||
updateObjectExplorerNodes(connectionProfile: IConnectionProfile): Promise<void>;
|
||||
updateObjectExplorerNodes(connectionProfile: IConnectionProfile, requestStatus?: ObjectExplorerRequestStatus | undefined): Promise<void>;
|
||||
|
||||
deleteObjectExplorerNode(connection: IConnectionProfile): Promise<void>;
|
||||
|
||||
@@ -208,10 +209,10 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
return this._onSelectionOrFocusChange.event;
|
||||
}
|
||||
|
||||
public async updateObjectExplorerNodes(connection: IConnectionProfile): Promise<void> {
|
||||
public async updateObjectExplorerNodes(connection: IConnectionProfile, requestStatus?: ObjectExplorerRequestStatus | undefined): Promise<void> {
|
||||
const withPassword = await this._connectionManagementService.addSavedPassword(connection);
|
||||
const connectionProfile = ConnectionProfile.fromIConnectionProfile(this._capabilitiesService, withPassword);
|
||||
return this.updateNewObjectExplorerNode(connectionProfile);
|
||||
return this.updateNewObjectExplorerNode(connectionProfile, requestStatus);
|
||||
}
|
||||
|
||||
public async deleteObjectExplorerNode(connection: IConnectionProfile): Promise<void> {
|
||||
@@ -327,12 +328,14 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
this._onUpdateObjectExplorerNodes.fire(eventArgs);
|
||||
}
|
||||
|
||||
private async updateNewObjectExplorerNode(connection: ConnectionProfile): Promise<void> {
|
||||
private async updateNewObjectExplorerNode(connection: ConnectionProfile, requestStatus: ObjectExplorerRequestStatus | undefined): Promise<void> {
|
||||
if (this._activeObjectExplorerNodes[connection.id]) {
|
||||
this.sendUpdateNodeEvent(connection);
|
||||
} else {
|
||||
try {
|
||||
await this.createNewSession(connection.providerName, connection);
|
||||
if (!requestStatus) {
|
||||
await this.createNewSession(connection.providerName, connection);
|
||||
}
|
||||
} catch (err) {
|
||||
this.sendUpdateNodeEvent(connection, err);
|
||||
throw err;
|
||||
@@ -352,6 +355,7 @@ export class ObjectExplorerService implements IObjectExplorerService {
|
||||
connection: connection,
|
||||
nodes: {}
|
||||
};
|
||||
|
||||
return result;
|
||||
} else {
|
||||
throw new Error(`Provider doesn't exist. id: ${providerId}`);
|
||||
|
||||
@@ -15,12 +15,17 @@ import { AsyncServerTree } from 'sql/workbench/services/objectExplorer/browser/a
|
||||
import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
|
||||
export interface ObjectExplorerRequestStatus {
|
||||
inProgress: boolean;
|
||||
}
|
||||
|
||||
export class TreeSelectionHandler {
|
||||
// progressRunner: IProgressRunner;
|
||||
|
||||
private _lastClicked: any[] | undefined;
|
||||
private _clickTimer: any = undefined;
|
||||
private _otherTimer: any = undefined;
|
||||
private _requestStatus: ObjectExplorerRequestStatus | undefined = undefined;
|
||||
|
||||
// constructor(@IProgressService private _progressService: IProgressService) {
|
||||
|
||||
@@ -50,13 +55,13 @@ export class TreeSelectionHandler {
|
||||
* Handle selection of tree element
|
||||
*/
|
||||
public onTreeSelect(event: any, tree: AsyncServerTree | ITree, connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService, capabilitiesService: ICapabilitiesService, connectionCompleteCallback: () => void) {
|
||||
let sendSelectionEvent = ((event: any, selection: any, isDoubleClick: boolean, userInteraction: boolean) => {
|
||||
let sendSelectionEvent = ((event: any, selection: any, isDoubleClick: boolean, userInteraction: boolean, requestStatus: ObjectExplorerRequestStatus | undefined = undefined) => {
|
||||
// userInteraction: defensive - don't touch this something else is handling it.
|
||||
if (userInteraction === true && this._lastClicked && this._lastClicked[0] === selection[0]) {
|
||||
this._lastClicked = undefined;
|
||||
}
|
||||
if (!TreeUpdateUtils.isInDragAndDrop) {
|
||||
this.handleTreeItemSelected(connectionManagementService, objectExplorerService, capabilitiesService, isDoubleClick, this.isKeyboardEvent(event), selection, tree, connectionCompleteCallback);
|
||||
this.handleTreeItemSelected(connectionManagementService, objectExplorerService, capabilitiesService, isDoubleClick, this.isKeyboardEvent(event), selection, tree, connectionCompleteCallback, requestStatus);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -82,12 +87,14 @@ export class TreeSelectionHandler {
|
||||
this._lastClicked = selection;
|
||||
|
||||
this._clickTimer = setTimeout(() => {
|
||||
// Sets request status object when timer is executed
|
||||
this._requestStatus = { inProgress: true };
|
||||
sendSelectionEvent(event, selection, false, true);
|
||||
}, 400);
|
||||
} else {
|
||||
clearTimeout(this._otherTimer);
|
||||
this._otherTimer = setTimeout(() => {
|
||||
sendSelectionEvent(event, selection, false, false);
|
||||
sendSelectionEvent(event, selection, false, false, this._requestStatus);
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
@@ -102,8 +109,9 @@ export class TreeSelectionHandler {
|
||||
* @param selection
|
||||
* @param tree
|
||||
* @param connectionCompleteCallback A function that gets called after a connection is established due to the selection, if needed
|
||||
* @param requestStatus Used to identify if a new session should be created or not to avoid creating back to back sessions
|
||||
*/
|
||||
private handleTreeItemSelected(connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService, capabilitiesService: ICapabilitiesService, isDoubleClick: boolean, isKeyboard: boolean, selection: any[], tree: AsyncServerTree | ITree, connectionCompleteCallback: () => void): void {
|
||||
private handleTreeItemSelected(connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService, capabilitiesService: ICapabilitiesService, isDoubleClick: boolean, isKeyboard: boolean, selection: any[], tree: AsyncServerTree | ITree, connectionCompleteCallback: () => void, requestStatus: ObjectExplorerRequestStatus | undefined): void {
|
||||
if (tree instanceof AsyncServerTree) {
|
||||
if (selection && selection.length > 0 && (selection[0] instanceof ConnectionProfile)) {
|
||||
if (!capabilitiesService.getCapabilities(selection[0].providerName)) {
|
||||
@@ -131,7 +139,12 @@ export class TreeSelectionHandler {
|
||||
if (connectionProfile) {
|
||||
this.onTreeActionStateChange(true);
|
||||
|
||||
TreeUpdateUtils.connectAndCreateOeSession(connectionProfile, options, connectionManagementService, objectExplorerService, tree).then(sessionCreated => {
|
||||
TreeUpdateUtils.connectAndCreateOeSession(connectionProfile, options, connectionManagementService, objectExplorerService, tree, requestStatus).then(sessionCreated => {
|
||||
// Clears request status object that was created when the first timeout callback is executed.
|
||||
if (this._requestStatus) {
|
||||
this._requestStatus = undefined;
|
||||
}
|
||||
|
||||
if (!sessionCreated) {
|
||||
this.onTreeActionStateChange(false);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import { TreeNode } from 'sql/workbench/services/objectExplorer/common/treeNode'
|
||||
import { Disposable, isDisposable } from 'vs/base/common/lifecycle';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { AsyncServerTree, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
|
||||
import { ObjectExplorerRequestStatus } from 'sql/workbench/services/objectExplorer/browser/treeSelectionHandler';
|
||||
|
||||
export interface IExpandableTree extends ITree {
|
||||
/**
|
||||
@@ -222,7 +223,7 @@ export class TreeUpdateUtils {
|
||||
* @param objectExplorerService Object explorer service instance
|
||||
*/
|
||||
public static async connectAndCreateOeSession(connection: ConnectionProfile, options: IConnectionCompletionOptions,
|
||||
connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService, tree: AsyncServerTree | ITree | undefined): Promise<boolean> {
|
||||
connectionManagementService: IConnectionManagementService, objectExplorerService: IObjectExplorerService, tree: AsyncServerTree | ITree | undefined, requestStatus?: ObjectExplorerRequestStatus | undefined): Promise<boolean> {
|
||||
const connectedConnection = await TreeUpdateUtils.connectIfNotConnected(connection, options, connectionManagementService, tree);
|
||||
if (connectedConnection) {
|
||||
// append group ID and original display name to build unique OE session ID
|
||||
@@ -231,7 +232,7 @@ export class TreeUpdateUtils {
|
||||
|
||||
let rootNode: TreeNode | undefined = objectExplorerService.getObjectExplorerNode(connectedConnection);
|
||||
if (!rootNode) {
|
||||
await objectExplorerService.updateObjectExplorerNodes(connectedConnection);
|
||||
await objectExplorerService.updateObjectExplorerNodes(connectedConnection, requestStatus);
|
||||
return true;
|
||||
// The oe request is sent. an event will be raised when the session is created
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user