Fix infinite callbacks in Azure Resource Explorer (#3780)

This commit is contained in:
Karl Burtram
2019-01-22 15:22:45 -08:00
committed by GitHub
parent 2e98fde053
commit 2b5265c103
4 changed files with 66 additions and 6 deletions

View File

@@ -90,12 +90,9 @@ export class AzureResourceAccountTreeNode extends AzureResourceContainerTreeNode
} }
} catch (error) { } catch (error) {
if (error instanceof AzureResourceCredentialError) { if (error instanceof AzureResourceCredentialError) {
this.appContext.apiWrapper.showErrorMessage(error.message);
this.appContext.apiWrapper.executeCommand('azure.resource.signin'); this.appContext.apiWrapper.executeCommand('azure.resource.signin');
} else {
return [AzureResourceMessageTreeNode.create(AzureResourceErrorMessageUtil.getErrorMessage(error), this)];
} }
return [AzureResourceMessageTreeNode.create(AzureResourceErrorMessageUtil.getErrorMessage(error), this)];
} }
} }

View File

@@ -32,7 +32,7 @@ export class AzureResourceTreeProvider implements TreeDataProvider<TreeNode>, IA
return element.getChildren(true); return element.getChildren(true);
} }
if (!this.isSystemInitialized) { if (!this.isSystemInitialized && !this._loadingTimer) {
this._loadingTimer = setInterval(async () => { this._loadingTimer = setInterval(async () => {
try { try {
// Call sqlops.accounts.getAllAccounts() to determine whether the system has been initialized. // Call sqlops.accounts.getAllAccounts() to determine whether the system has been initialized.

View File

@@ -41,3 +41,56 @@ export function generateGuid(): string {
return oct.substr(0, 8) + '-' + oct.substr(9, 4) + '-4' + oct.substr(13, 3) + '-' + clockSequenceHi + oct.substr(16, 3) + '-' + oct.substr(19, 12); return oct.substr(0, 8) + '-' + oct.substr(9, 4) + '-4' + oct.substr(13, 3) + '-' + clockSequenceHi + oct.substr(16, 3) + '-' + oct.substr(19, 12);
/* tslint:enable:no-bitwise */ /* tslint:enable:no-bitwise */
} }
export function equals(one: any, other: any): boolean {
if (one === other) {
return true;
}
if (one === null || one === undefined || other === null || other === undefined) {
return false;
}
if (typeof one !== typeof other) {
return false;
}
if (typeof one !== 'object') {
return false;
}
if ((Array.isArray(one)) !== (Array.isArray(other))) {
return false;
}
let i: number;
let key: string;
if (Array.isArray(one)) {
if (one.length !== other.length) {
return false;
}
for (i = 0; i < one.length; i++) {
if (!equals(one[i], other[i])) {
return false;
}
}
} else {
const oneKeys: string[] = [];
for (key in one) {
oneKeys.push(key);
}
oneKeys.sort();
const otherKeys: string[] = [];
for (key in other) {
otherKeys.push(key);
}
otherKeys.sort();
if (!equals(oneKeys, otherKeys)) {
return false;
}
for (i = 0; i < oneKeys.length; i++) {
if (!equals(one[oneKeys[i]], other[oneKeys[i]])) {
return false;
}
}
}
return true;
}

View File

@@ -25,6 +25,7 @@ import { AzureResourceTenantService } from '../azureResource/services/tenantServ
import { registerAzureResourceDatabaseServerCommands } from '../azureResource/providers/databaseServer/commands'; import { registerAzureResourceDatabaseServerCommands } from '../azureResource/providers/databaseServer/commands';
import { registerAzureResourceDatabaseCommands } from '../azureResource/providers/database/commands'; import { registerAzureResourceDatabaseCommands } from '../azureResource/providers/database/commands';
import { equals } from '../azureResource/utils';
export default class AzureResourceController extends ControllerBase { export default class AzureResourceController extends ControllerBase {
public activate(): Promise<boolean> { public activate(): Promise<boolean> {
@@ -37,7 +38,16 @@ export default class AzureResourceController extends ControllerBase {
const azureResourceTree = new AzureResourceTreeProvider(this.appContext); const azureResourceTree = new AzureResourceTreeProvider(this.appContext);
this.extensionContext.subscriptions.push(this.apiWrapper.registerTreeDataProvider('azureResourceExplorer', azureResourceTree)); this.extensionContext.subscriptions.push(this.apiWrapper.registerTreeDataProvider('azureResourceExplorer', azureResourceTree));
this.appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService).onDidChangeAccounts((e: DidChangeAccountsParams) => { azureResourceTree.notifyNodeChanged(undefined); }); let previousAccounts = undefined;
this.appContext.getService<IAzureResourceAccountService>(AzureResourceServiceNames.accountService).onDidChangeAccounts((e: DidChangeAccountsParams) => {
// the onDidChangeAccounts event will trigger in many cases where the accounts didn't actually change
// the notifyNodeChanged event triggers a refresh which triggers a getChildren which can trigger this callback
// this below check short-circuits the infinite callback loop
if (!equals(e.accounts, previousAccounts)) {
azureResourceTree.notifyNodeChanged(undefined);
}
previousAccounts = e.accounts;
});
registerAzureResourceCommands(this.appContext, azureResourceTree); registerAzureResourceCommands(this.appContext, azureResourceTree);