avoid unnecessary connections in azure view (#20817)

* avoid unnecessary connections in azure view

* pr comments
This commit is contained in:
Alan Ren
2022-10-12 20:00:09 -07:00
committed by GitHub
parent 51d5f07c77
commit 359e9657c5
3 changed files with 18 additions and 32 deletions

View File

@@ -29,7 +29,11 @@ export interface ITreeItem extends vsITreeItem {
payload?: IConnectionProfile; // its possible we will want this to be more generic payload?: IConnectionProfile; // its possible we will want this to be more generic
sqlIcon?: string; sqlIcon?: string;
type?: NodeType; type?: NodeType;
nodeInfo?: NodeInfo nodeInfo?: NodeInfo;
/**
* The Object Explorer session id that the tree item belongs to.
*/
sessionId?: string;
} }
export interface ITreeView extends vsITreeView { export interface ITreeView extends vsITreeView {

View File

@@ -19,7 +19,7 @@ CommandsRegistry.registerCommand({
handler: (accessor, args: TreeViewItemHandleArg) => { handler: (accessor, args: TreeViewItemHandleArg) => {
if (args.$treeItem) { if (args.$treeItem) {
const oeService = accessor.get(IOEShimService); const oeService = accessor.get(IOEShimService);
return oeService.disconnectNode(args.$treeViewId, args.$treeItem).then(() => { return oeService.disconnectNode(args.$treeItem).then(() => {
const { treeView } = (<ICustomViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(args.$treeViewId)); const { treeView } = (<ICustomViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(args.$treeViewId));
// we need to collapse it then refresh it so that the tree doesn't try and use it's cache next time the user expands the node // we need to collapse it then refresh it so that the tree doesn't try and use it's cache next time the user expands the node
treeView.collapse(args.$treeItem); treeView.collapse(args.$treeItem);

View File

@@ -27,7 +27,7 @@ export const IOEShimService = createDecorator<IOEShimService>(SERVICE_ID);
export interface IOEShimService { export interface IOEShimService {
_serviceBrand: undefined; _serviceBrand: undefined;
getChildren(node: ITreeItem, viewId: string): Promise<ITreeItem[]>; getChildren(node: ITreeItem, viewId: string): Promise<ITreeItem[]>;
disconnectNode(viewId: string, node: ITreeItem): Promise<boolean>; disconnectNode(node: ITreeItem): Promise<boolean>;
providerExists(providerId: string): boolean; providerExists(providerId: string): boolean;
isNodeConnected(viewId: string, node: ITreeItem): boolean; isNodeConnected(viewId: string, node: ITreeItem): boolean;
getNodeInfoForTreeItem(treeItem: ITreeItem): azdata.NodeInfo | undefined; getNodeInfoForTreeItem(treeItem: ITreeItem): azdata.NodeInfo | undefined;
@@ -36,7 +36,6 @@ export interface IOEShimService {
export class OEShimService extends Disposable implements IOEShimService { export class OEShimService extends Disposable implements IOEShimService {
_serviceBrand: undefined; _serviceBrand: undefined;
private sessionMap = new Map<number, string>();
private nodeHandleMap = new Map<number, string>(); private nodeHandleMap = new Map<number, string>();
private nodeInfoMap = new Map<ITreeItem, azdata.NodeInfo>(); private nodeInfoMap = new Map<ITreeItem, azdata.NodeInfo>();
@@ -110,28 +109,12 @@ export class OEShimService extends Disposable implements IOEShimService {
return connProfile; return connProfile;
} }
public async disconnectNode(viewId: string, node: ITreeItem): Promise<boolean> { public async disconnectNode(node: ITreeItem): Promise<boolean> {
// we assume only nodes with payloads can be connected if (node.sessionId !== undefined) {
// check to make sure we have an existing connection const closed = (await this.oe.closeSession(node.childProvider!, this.oe.getSession(node.sessionId)!))!.success;
let key = generateSessionMapKey(viewId, node);
let session = this.sessionMap.get(key);
if (session) {
let closed = (await this.oe.closeSession(node.childProvider!, this.oe.getSession(session)!))!.success;
if (closed) {
this.sessionMap.delete(key);
}
return closed; return closed;
} }
return Promise.resolve(false); return false;
}
private async getOrCreateSession(viewId: string, node: ITreeItem): Promise<string> {
// verify the map is correct
let key = generateSessionMapKey(viewId, node);
if (!this.sessionMap.has(key)) {
this.sessionMap.set(key, await this.createSession(viewId, node.childProvider!, node));
}
return this.sessionMap.get(key)!;
} }
public async getChildren(node: ITreeItem, viewId: string): Promise<ITreeItem[]> { public async getChildren(node: ITreeItem, viewId: string): Promise<ITreeItem[]> {
@@ -140,13 +123,15 @@ export class OEShimService extends Disposable implements IOEShimService {
node.payload.authenticationType = this.getDefaultAuthenticationType(this.configurationService); // we need to set auth type here, because it's value is part of the session key node.payload.authenticationType = this.getDefaultAuthenticationType(this.configurationService); // we need to set auth type here, because it's value is part of the session key
} }
const sessionId = await this.getOrCreateSession(viewId, node); if (node.sessionId === undefined) {
node.sessionId = await this.createSession(viewId, node.childProvider!, node);
}
const requestHandle = this.nodeHandleMap.get(generateNodeMapKey(viewId, node)) || node.handle; const requestHandle = this.nodeHandleMap.get(generateNodeMapKey(viewId, node)) || node.handle;
const treeNode = new TreeNode(undefined!, undefined!, undefined!, undefined!, requestHandle, undefined!); // hack since this entire system is a hack anyways const treeNode = new TreeNode(undefined!, undefined!, undefined!, undefined!, requestHandle, undefined!); // hack since this entire system is a hack anyways
treeNode.connection = new ConnectionProfile(this.capabilities, node.payload); treeNode.connection = new ConnectionProfile(this.capabilities, node.payload);
const childrenNodes = await this.oe.refreshTreeNode({ const childrenNodes = await this.oe.refreshTreeNode({
success: true, success: true,
sessionId, sessionId: node.sessionId!,
rootNode: undefined!, // hack since this entire system is a hack anyways rootNode: undefined!, // hack since this entire system is a hack anyways
errorMessage: undefined errorMessage: undefined
}, treeNode); }, treeNode);
@@ -209,7 +194,8 @@ export class OEShimService extends Disposable implements IOEShimService {
payload: node.payload || (databaseChanged ? updatedPayload : parentNode.payload), payload: node.payload || (databaseChanged ? updatedPayload : parentNode.payload),
contextValue: node.nodeTypeId, contextValue: node.nodeTypeId,
sqlIcon: icon, sqlIcon: icon,
nodeInfo: nodeInfo nodeInfo: nodeInfo,
sessionId: parentNode.sessionId
}; };
this.nodeHandleMap.set(generateNodeMapKey(viewId, newTreeItem), nodePath); this.nodeHandleMap.set(generateNodeMapKey(viewId, newTreeItem), nodePath);
this.nodeInfoMap.set(newTreeItem, nodeInfo); this.nodeInfoMap.set(newTreeItem, nodeInfo);
@@ -221,7 +207,7 @@ export class OEShimService extends Disposable implements IOEShimService {
} }
public isNodeConnected(viewId: string, node: ITreeItem): boolean { public isNodeConnected(viewId: string, node: ITreeItem): boolean {
return this.sessionMap.has(generateSessionMapKey(viewId, node)); return node.sessionId !== undefined;
} }
public getNodeInfoForTreeItem(treeItem: ITreeItem): azdata.NodeInfo | undefined { public getNodeInfoForTreeItem(treeItem: ITreeItem): azdata.NodeInfo | undefined {
@@ -236,10 +222,6 @@ export class OEShimService extends Disposable implements IOEShimService {
} }
} }
function generateSessionMapKey(viewId: string, node: ITreeItem): number {
return hash([viewId, node.childProvider, node.payload]);
}
function generateNodeMapKey(viewId: string, node: ITreeItem): number { function generateNodeMapKey(viewId: string, node: ITreeItem): number {
return hash([viewId, node.handle]); return hash([viewId, node.handle]);
} }