mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Fix some connection listener leaks (#6357)
* Fix some connection listener leaks * More descriptive name and update summary * Dispose some more connections and fix a few spelling errors
This commit is contained in:
@@ -55,7 +55,7 @@ export interface ICapabilitiesService {
|
|||||||
isFeatureAvailable(action: IAction, connectionManagementInfo: ConnectionManagementInfo): boolean;
|
isFeatureAvailable(action: IAction, connectionManagementInfo: ConnectionManagementInfo): boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When a new capabilities is registered, it emits the provider name, be to use to get the new capabilities
|
* When new capabilities are registered, it emits the @see ProviderFeatures, which can be used to get the new capabilities
|
||||||
*/
|
*/
|
||||||
readonly onCapabilitiesRegistered: Event<ProviderFeatures>;
|
readonly onCapabilitiesRegistered: Event<ProviderFeatures>;
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ interface CapabilitiesMomento {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Capabilities service implementation class. This class provides the ability
|
* Capabilities service implementation class. This class provides the ability
|
||||||
* to discover the DMP capabilties that a DMP provider offers.
|
* to discover the DMP capabilities that a DMP provider offers.
|
||||||
*/
|
*/
|
||||||
export class CapabilitiesService extends Disposable implements ICapabilitiesService {
|
export class CapabilitiesService extends Disposable implements ICapabilitiesService {
|
||||||
_serviceBrand: any;
|
_serviceBrand: any;
|
||||||
@@ -50,7 +50,7 @@ export class CapabilitiesService extends Disposable implements ICapabilitiesServ
|
|||||||
constructor(
|
constructor(
|
||||||
@IStorageService private _storageService: IStorageService,
|
@IStorageService private _storageService: IStorageService,
|
||||||
@IExtensionService extensionService: IExtensionService,
|
@IExtensionService extensionService: IExtensionService,
|
||||||
@IExtensionManagementService extentionManagementService: IExtensionManagementService
|
@IExtensionManagementService extensionManagementService: IExtensionManagementService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@@ -78,7 +78,7 @@ export class CapabilitiesService extends Disposable implements ICapabilitiesServ
|
|||||||
|
|
||||||
_storageService.onWillSaveState(() => this.shutdown());
|
_storageService.onWillSaveState(() => this.shutdown());
|
||||||
|
|
||||||
this._register(extentionManagementService.onDidUninstallExtension(({ identifier }) => {
|
this._register(extensionManagementService.onDidUninstallExtension(({ identifier }) => {
|
||||||
const connectionProvider = 'connectionProvider';
|
const connectionProvider = 'connectionProvider';
|
||||||
extensionService.getExtensions().then(i => {
|
extensionService.getExtensions().then(i => {
|
||||||
let extension = i.find(c => c.identifier.value.toLowerCase() === identifier.id.toLowerCase());
|
let extension = i.find(c => c.identifier.value.toLowerCase() === identifier.id.toLowerCase());
|
||||||
|
|||||||
@@ -691,7 +691,10 @@ export class ConnectionManagementService extends Disposable implements IConnecti
|
|||||||
}
|
}
|
||||||
|
|
||||||
public hasRegisteredServers(): boolean {
|
public hasRegisteredServers(): boolean {
|
||||||
return this.doHasRegisteredServers(this.getConnectionGroups());
|
const groups: ConnectionProfileGroup[] = this.getConnectionGroups();
|
||||||
|
const hasRegisteredServers: boolean = this.doHasRegisteredServers(groups);
|
||||||
|
groups.forEach(cpg => cpg.dispose());
|
||||||
|
return hasRegisteredServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
private doHasRegisteredServers(root: ConnectionProfileGroup[]): boolean {
|
private doHasRegisteredServers(root: ConnectionProfileGroup[]): boolean {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile';
|
||||||
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
|
||||||
export interface IConnectionProfileGroup {
|
export interface IConnectionProfileGroup {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -13,7 +14,7 @@ export interface IConnectionProfileGroup {
|
|||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConnectionProfileGroup implements IConnectionProfileGroup {
|
export class ConnectionProfileGroup extends Disposable implements IConnectionProfileGroup {
|
||||||
|
|
||||||
public children: ConnectionProfileGroup[];
|
public children: ConnectionProfileGroup[];
|
||||||
public connections: ConnectionProfile[];
|
public connections: ConnectionProfile[];
|
||||||
@@ -26,6 +27,7 @@ export class ConnectionProfileGroup implements IConnectionProfileGroup {
|
|||||||
public color: string,
|
public color: string,
|
||||||
public description: string
|
public description: string
|
||||||
) {
|
) {
|
||||||
|
super();
|
||||||
this.parentId = parent ? parent.id : undefined;
|
this.parentId = parent ? parent.id : undefined;
|
||||||
if (this.name === ConnectionProfileGroup.RootGroupName) {
|
if (this.name === ConnectionProfileGroup.RootGroupName) {
|
||||||
this.name = '';
|
this.name = '';
|
||||||
@@ -100,9 +102,8 @@ export class ConnectionProfileGroup implements IConnectionProfileGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChildren(): any {
|
public getChildren(): (ConnectionProfile | ConnectionProfileGroup)[] {
|
||||||
let allChildren = [];
|
let allChildren: (ConnectionProfile | ConnectionProfileGroup)[] = [];
|
||||||
|
|
||||||
if (this.connections) {
|
if (this.connections) {
|
||||||
this.connections.forEach((conn) => {
|
this.connections.forEach((conn) => {
|
||||||
allChildren.push(conn);
|
allChildren.push(conn);
|
||||||
@@ -131,6 +132,7 @@ export class ConnectionProfileGroup implements IConnectionProfileGroup {
|
|||||||
connections.forEach((conn) => {
|
connections.forEach((conn) => {
|
||||||
this.connections = this.connections.filter((curConn) => { return curConn.id !== conn.id; });
|
this.connections = this.connections.filter((curConn) => { return curConn.id !== conn.id; });
|
||||||
conn.parent = this;
|
conn.parent = this;
|
||||||
|
this._register(conn);
|
||||||
this.connections.push(conn);
|
this.connections.push(conn);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -143,6 +145,7 @@ export class ConnectionProfileGroup implements IConnectionProfileGroup {
|
|||||||
groups.forEach((group) => {
|
groups.forEach((group) => {
|
||||||
this.children = this.children.filter((grp) => { return group.id !== grp.id; });
|
this.children = this.children.filter((grp) => { return group.id !== grp.id; });
|
||||||
group.parent = this;
|
group.parent = this;
|
||||||
|
this._register(group);
|
||||||
this.children.push(group);
|
this.children.push(group);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { isString } from 'vs/base/common/types';
|
import { isString } from 'vs/base/common/types';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
@@ -19,6 +19,7 @@ export class ProviderConnectionInfo extends Disposable implements azdata.Connect
|
|||||||
options: { [name: string]: any } = {};
|
options: { [name: string]: any } = {};
|
||||||
|
|
||||||
private _providerName: string;
|
private _providerName: string;
|
||||||
|
private _onCapabilitiesRegisteredDisposable: IDisposable;
|
||||||
protected _serverCapabilities: ConnectionProviderProperties;
|
protected _serverCapabilities: ConnectionProviderProperties;
|
||||||
private static readonly SqlAuthentication = 'SqlLogin';
|
private static readonly SqlAuthentication = 'SqlLogin';
|
||||||
public static readonly ProviderPropertyName = 'providerName';
|
public static readonly ProviderPropertyName = 'providerName';
|
||||||
@@ -74,14 +75,24 @@ export class ProviderConnectionInfo extends Disposable implements azdata.Connect
|
|||||||
if (capabilities) {
|
if (capabilities) {
|
||||||
this._serverCapabilities = capabilities.connection;
|
this._serverCapabilities = capabilities.connection;
|
||||||
}
|
}
|
||||||
this._register(this.capabilitiesService.onCapabilitiesRegistered(e => {
|
if (this._onCapabilitiesRegisteredDisposable) {
|
||||||
|
dispose(this._onCapabilitiesRegisteredDisposable);
|
||||||
|
}
|
||||||
|
this._onCapabilitiesRegisteredDisposable = this.capabilitiesService.onCapabilitiesRegistered(e => {
|
||||||
if (e.connection.providerId === this.providerName) {
|
if (e.connection.providerId === this.providerName) {
|
||||||
this._serverCapabilities = e.connection;
|
this._serverCapabilities = e.connection;
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
if (this._onCapabilitiesRegisteredDisposable) {
|
||||||
|
dispose(this._onCapabilitiesRegisteredDisposable);
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
public clone(): ProviderConnectionInfo {
|
public clone(): ProviderConnectionInfo {
|
||||||
let instance = new ProviderConnectionInfo(this.capabilitiesService, this.providerName);
|
let instance = new ProviderConnectionInfo(this.capabilitiesService, this.providerName);
|
||||||
instance.options = Object.assign({}, this.options);
|
instance.options = Object.assign({}, this.options);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType';
|
|||||||
import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode';
|
import { TreeNode } from 'sql/workbench/parts/objectExplorer/common/treeNode';
|
||||||
import * as errors from 'vs/base/common/errors';
|
import * as errors from 'vs/base/common/errors';
|
||||||
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
import { IConnectionProfile } from 'sql/platform/connection/common/interfaces';
|
||||||
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
|
|
||||||
export interface IExpandableTree extends ITree {
|
export interface IExpandableTree extends ITree {
|
||||||
// {{SQL CARBON EDIT }} - add back deleted VS Code tree methods
|
// {{SQL CARBON EDIT }} - add back deleted VS Code tree methods
|
||||||
@@ -72,8 +73,11 @@ export class TreeUpdateUtils {
|
|||||||
} else if (viewKey === 'saved') {
|
} else if (viewKey === 'saved') {
|
||||||
treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService, providers);
|
treeInput = TreeUpdateUtils.getTreeInput(connectionManagementService, providers);
|
||||||
}
|
}
|
||||||
|
const previousTreeInput: any = tree.getInput();
|
||||||
return tree.setInput(treeInput).then(() => {
|
return tree.setInput(treeInput).then(() => {
|
||||||
|
if (previousTreeInput instanceof Disposable) {
|
||||||
|
previousTreeInput.dispose();
|
||||||
|
}
|
||||||
// Make sure to expand all folders that where expanded in the previous session
|
// Make sure to expand all folders that where expanded in the previous session
|
||||||
if (targetsToExpand) {
|
if (targetsToExpand) {
|
||||||
tree.expandAll(targetsToExpand);
|
tree.expandAll(targetsToExpand);
|
||||||
@@ -135,6 +139,7 @@ export class TreeUpdateUtils {
|
|||||||
if (groups && groups.length > 0) {
|
if (groups && groups.length > 0) {
|
||||||
let treeInput = groups[0];
|
let treeInput = groups[0];
|
||||||
treeInput.name = 'root';
|
treeInput.name = 'root';
|
||||||
|
groups.forEach(cpg => cpg.dispose());
|
||||||
return treeInput;
|
return treeInput;
|
||||||
}
|
}
|
||||||
// Should never get to this case.
|
// Should never get to this case.
|
||||||
|
|||||||
@@ -117,22 +117,22 @@ export class ConnectionController implements IConnectionComponentController {
|
|||||||
this._connectionWidget.createConnectionWidget(container);
|
this._connectionWidget.createConnectionWidget(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getServerGroupHelper(group: ConnectionProfileGroup, groupNames: IConnectionProfileGroup[]): void {
|
private flattenGroups(group: ConnectionProfileGroup, allGroups: IConnectionProfileGroup[]): void {
|
||||||
if (group) {
|
if (group) {
|
||||||
if (group.fullName !== '') {
|
if (group.fullName !== '') {
|
||||||
groupNames.push(group);
|
allGroups.push(group);
|
||||||
}
|
}
|
||||||
if (group.hasChildren()) {
|
if (group.hasChildren()) {
|
||||||
group.children.forEach((child) => this.getServerGroupHelper(child, groupNames));
|
group.children.forEach((child) => this.flattenGroups(child, allGroups));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getAllServerGroups(providers?: string[]): IConnectionProfileGroup[] {
|
private getAllServerGroups(providers?: string[]): IConnectionProfileGroup[] {
|
||||||
let connectionGroupRoot = this._connectionManagementService.getConnectionGroups(providers);
|
let connectionGroupRoot = this._connectionManagementService.getConnectionGroups(providers);
|
||||||
let connectionGroupNames: IConnectionProfileGroup[] = [];
|
let allGroups: IConnectionProfileGroup[] = [];
|
||||||
if (connectionGroupRoot && connectionGroupRoot.length > 0) {
|
if (connectionGroupRoot && connectionGroupRoot.length > 0) {
|
||||||
this.getServerGroupHelper(connectionGroupRoot[0], connectionGroupNames);
|
this.flattenGroups(connectionGroupRoot[0], allGroups);
|
||||||
}
|
}
|
||||||
let defaultGroupId: string;
|
let defaultGroupId: string;
|
||||||
if (connectionGroupRoot && connectionGroupRoot.length > 0 && ConnectionProfileGroup.isRoot(connectionGroupRoot[0].name)) {
|
if (connectionGroupRoot && connectionGroupRoot.length > 0 && ConnectionProfileGroup.isRoot(connectionGroupRoot[0].name)) {
|
||||||
@@ -140,9 +140,10 @@ export class ConnectionController implements IConnectionComponentController {
|
|||||||
} else {
|
} else {
|
||||||
defaultGroupId = Utils.defaultGroupId;
|
defaultGroupId = Utils.defaultGroupId;
|
||||||
}
|
}
|
||||||
connectionGroupNames.push(Object.assign({}, this._connectionWidget.DefaultServerGroup, { id: defaultGroupId }));
|
allGroups.push(Object.assign({}, this._connectionWidget.DefaultServerGroup, { id: defaultGroupId }));
|
||||||
connectionGroupNames.push(this._connectionWidget.NoneServerGroup);
|
allGroups.push(this._connectionWidget.NoneServerGroup);
|
||||||
return connectionGroupNames;
|
connectionGroupRoot.forEach(cpg => cpg.dispose());
|
||||||
|
return allGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public initDialog(providers: string[], connectionInfo: IConnectionProfile): void {
|
public initDialog(providers: string[], connectionInfo: IConnectionProfile): void {
|
||||||
|
|||||||
@@ -316,8 +316,11 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._model.providerName = this._currentProviderType;
|
this._model.providerName = this._currentProviderType;
|
||||||
|
const previousModel = this._model;
|
||||||
this._model = new ConnectionProfile(this._capabilitiesService, this._model);
|
this._model = new ConnectionProfile(this._capabilitiesService, this._model);
|
||||||
|
if (previousModel) {
|
||||||
|
previousModel.dispose();
|
||||||
|
}
|
||||||
if (this._inputModel && this._inputModel.options) {
|
if (this._inputModel && this._inputModel.options) {
|
||||||
this.uiController.showUiComponent(input.container,
|
this.uiController.showUiComponent(input.container,
|
||||||
this._inputModel.options.authTypeChanged);
|
this._inputModel.options.authTypeChanged);
|
||||||
@@ -333,9 +336,12 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
|||||||
|
|
||||||
private handleFillInConnectionInputs(connectionInfo: IConnectionProfile): void {
|
private handleFillInConnectionInputs(connectionInfo: IConnectionProfile): void {
|
||||||
this._connectionManagementService.addSavedPassword(connectionInfo).then(connectionWithPassword => {
|
this._connectionManagementService.addSavedPassword(connectionInfo).then(connectionWithPassword => {
|
||||||
let model = this.createModel(connectionWithPassword);
|
if (this._model) {
|
||||||
this._model = model;
|
this._model.dispose();
|
||||||
this.uiController.fillInConnectionInputs(model);
|
}
|
||||||
|
this._model = this.createModel(connectionWithPassword);
|
||||||
|
|
||||||
|
this.uiController.fillInConnectionInputs(this._model);
|
||||||
});
|
});
|
||||||
this._connectionDialog.updateProvider(this._providerNameToDisplayNameMap[connectionInfo.providerName]);
|
this._connectionDialog.updateProvider(this._providerNameToDisplayNameMap[connectionInfo.providerName]);
|
||||||
}
|
}
|
||||||
@@ -349,6 +355,9 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private updateModelServerCapabilities(model: IConnectionProfile) {
|
private updateModelServerCapabilities(model: IConnectionProfile) {
|
||||||
|
if (this._model) {
|
||||||
|
this._model.dispose();
|
||||||
|
}
|
||||||
this._model = this.createModel(model);
|
this._model = this.createModel(model);
|
||||||
if (this._model.providerName) {
|
if (this._model.providerName) {
|
||||||
this._currentProviderType = this._model.providerName;
|
this._currentProviderType = this._model.providerName;
|
||||||
@@ -452,8 +461,10 @@ export class ConnectionDialogService implements IConnectionDialogService {
|
|||||||
this._connectionDialog.updateProvider(this._providerNameToDisplayNameMap[this._currentProviderType]);
|
this._connectionDialog.updateProvider(this._providerNameToDisplayNameMap[this._currentProviderType]);
|
||||||
|
|
||||||
return new Promise<void>(() => {
|
return new Promise<void>(() => {
|
||||||
this._connectionDialog.open(this._connectionManagementService.getRecentConnections(params.providers).length > 0);
|
const recentConnections: ConnectionProfile[] = this._connectionManagementService.getRecentConnections(params.providers);
|
||||||
|
this._connectionDialog.open(recentConnections.length > 0);
|
||||||
this.uiController.focusOnOpen();
|
this.uiController.focusOnOpen();
|
||||||
|
recentConnections.forEach(conn => conn.dispose());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -321,10 +321,14 @@ export class ConnectionDialogWidget extends Modal {
|
|||||||
const actionProvider = this._instantiationService.createInstance(RecentConnectionActionsProvider);
|
const actionProvider = this._instantiationService.createInstance(RecentConnectionActionsProvider);
|
||||||
const controller = new RecentConnectionTreeController(leftClick, actionProvider, this._connectionManagementService, this._contextMenuService);
|
const controller = new RecentConnectionTreeController(leftClick, actionProvider, this._connectionManagementService, this._contextMenuService);
|
||||||
actionProvider.onRecentConnectionRemoved(() => {
|
actionProvider.onRecentConnectionRemoved(() => {
|
||||||
this.open(this._connectionManagementService.getRecentConnections().length > 0);
|
const recentConnections: ConnectionProfile[] = this._connectionManagementService.getRecentConnections();
|
||||||
|
this.open(recentConnections.length > 0);
|
||||||
|
recentConnections.forEach(conn => conn.dispose());
|
||||||
});
|
});
|
||||||
controller.onRecentConnectionRemoved(() => {
|
controller.onRecentConnectionRemoved(() => {
|
||||||
this.open(this._connectionManagementService.getRecentConnections().length > 0);
|
const recentConnections: ConnectionProfile[] = this._connectionManagementService.getRecentConnections();
|
||||||
|
this.open(recentConnections.length > 0);
|
||||||
|
recentConnections.forEach(conn => conn.dispose());
|
||||||
});
|
});
|
||||||
this._recentConnectionTree = TreeCreationUtils.createConnectionTree(treeContainer, this._instantiationService, controller);
|
this._recentConnectionTree = TreeCreationUtils.createConnectionTree(treeContainer, this._instantiationService, controller);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user