diff --git a/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts b/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts index 037755cac0..7d10345d54 100644 --- a/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts +++ b/extensions/sql-migration/src/dashboard/sqlServerDashboard.ts @@ -49,6 +49,8 @@ export class DashboardWidget { private _autoRefreshHandle!: NodeJS.Timeout; private _disposables: vscode.Disposable[] = []; + private isRefreshing: boolean = false; + constructor() { } @@ -242,14 +244,19 @@ export class DashboardWidget { } private setAutoRefresh(interval: SupportedAutoRefreshIntervals): void { - let classVariable = this; + const classVariable = this; clearInterval(this._autoRefreshHandle); if (interval !== -1) { - this._autoRefreshHandle = setInterval(function () { classVariable.refreshMigrations(); }, interval); + this._autoRefreshHandle = setInterval(async function () { await classVariable.refreshMigrations(); }, interval); } } private async refreshMigrations(): Promise { + if (this.isRefreshing) { + return; + } + + this.isRefreshing = true; this._viewAllMigrationsButton.enabled = false; this._migrationStatusCardLoadingContainer.loading = true; try { @@ -304,6 +311,7 @@ export class DashboardWidget { } catch (error) { console.log(error); } finally { + this.isRefreshing = false; this._migrationStatusCardLoadingContainer.loading = false; this._viewAllMigrationsButton.enabled = true; } diff --git a/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts b/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts index 03b06503d3..e25eddc2d0 100644 --- a/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts +++ b/extensions/sql-migration/src/dialog/migrationCutover/migrationCutoverDialog.ts @@ -44,6 +44,8 @@ export class MigrationCutoverDialog { private _autoRefreshHandle!: any; private _disposables: vscode.Disposable[] = []; + private isRefreshing = false; + readonly _infoFieldWidth: string = '250px'; constructor(migration: MigrationContext) { @@ -279,8 +281,8 @@ export class MigrationCutoverDialog { d => { try { d.dispose(); } catch { } }); })); - return view.initializeModel(form).then((value) => { - this.refreshStatus(); + return view.initializeModel(form).then(async (value) => { + await this.refreshStatus(); }); } catch (e) { console.log(e); @@ -493,13 +495,18 @@ export class MigrationCutoverDialog { const classVariable = this; clearInterval(this._autoRefreshHandle); if (interval !== -1) { - this._autoRefreshHandle = setInterval(function () { classVariable.refreshStatus(); }, interval); + this._autoRefreshHandle = setInterval(async function () { await classVariable.refreshStatus(); }, interval); } } private async refreshStatus(): Promise { + if (this.isRefreshing) { + return; + } + try { + this.isRefreshing = true; this._refreshLoader.loading = true; this._cutoverButton.enabled = false; this._cancelButton.enabled = false; @@ -615,8 +622,10 @@ export class MigrationCutoverDialog { } } catch (e) { console.log(e); + } finally { + this.isRefreshing = false; + this._refreshLoader.loading = false; } - this._refreshLoader.loading = false; } private createInfoField(label: string, value: string): { diff --git a/extensions/sql-migration/src/dialog/migrationStatus/migrationStatusDialog.ts b/extensions/sql-migration/src/dialog/migrationStatus/migrationStatusDialog.ts index 5837ca2222..d1bd0a5b36 100644 --- a/extensions/sql-migration/src/dialog/migrationStatus/migrationStatusDialog.ts +++ b/extensions/sql-migration/src/dialog/migrationStatus/migrationStatusDialog.ts @@ -33,6 +33,8 @@ export class MigrationStatusDialog { private _autoRefreshHandle!: NodeJS.Timeout; private _disposables: vscode.Disposable[] = []; + private isRefreshing = false; + constructor(migrations: MigrationContext[], private _filter: AdsMigrationStatus) { this._model = new MigrationStatusDialogModel(migrations); this._dialogObject = azdata.window.createModelViewDialog(loc.MIGRATION_STATUS, 'MigrationControllerDialog', 'wide'); @@ -109,19 +111,16 @@ export class MigrationStatusDialog { })); this._refresh = this._view.modelBuilder.button().withProps({ - iconPath: { - light: IconPathHelper.refresh.light, - dark: IconPathHelper.refresh.dark - }, + iconPath: IconPathHelper.refresh, iconHeight: '16px', iconWidth: '20px', height: '30px', label: loc.REFRESH_BUTTON_LABEL, }).component(); - this._disposables.push(this._refresh.onDidClick((e) => { - this.refreshTable(); - })); + this._disposables.push( + this._refresh.onDidClick( + async (e) => { await this.refreshTable(); })); const flexContainer = this._view.modelBuilder.flexContainer().withProps({ width: 900, @@ -169,7 +168,7 @@ export class MigrationStatusDialog { const classVariable = this; clearInterval(this._autoRefreshHandle); if (interval !== -1) { - this._autoRefreshHandle = setInterval(function () { classVariable.refreshTable(); }, interval); + this._autoRefreshHandle = setInterval(async function () { await classVariable.refreshTable(); }, interval); } } @@ -447,11 +446,22 @@ export class MigrationStatusDialog { } private async refreshTable(): Promise { - this._refreshLoader.loading = true; - const currentConnection = await azdata.connection.getCurrentConnection(); - this._model._migrations = await MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection, true); - await this.populateMigrationTable(); - this._refreshLoader.loading = false; + if (this.isRefreshing) { + return; + } + + this.isRefreshing = true; + try { + this._refreshLoader.loading = true; + const currentConnection = await azdata.connection.getCurrentConnection(); + this._model._migrations = await MigrationLocalStorage.getMigrationsBySourceConnections(currentConnection, true); + await this.populateMigrationTable(); + } catch (e) { + console.log(e); + } finally { + this.isRefreshing = false; + this._refreshLoader.loading = false; + } } private createStatusTable(): azdata.DeclarativeTableComponent { diff --git a/extensions/sql-migration/src/models/migrationLocalStorage.ts b/extensions/sql-migration/src/models/migrationLocalStorage.ts index b4be494613..bce85cb406 100644 --- a/extensions/sql-migration/src/models/migrationLocalStorage.ts +++ b/extensions/sql-migration/src/models/migrationLocalStorage.ts @@ -16,7 +16,7 @@ export class MigrationLocalStorage { } public static async getMigrationsBySourceConnections(connectionProfile: azdata.connection.ConnectionProfile, refreshStatus?: boolean): Promise { - + const undefinedSessionId = '{undefined}'; const result: MigrationContext[] = []; const validMigrations: MigrationContext[] = []; @@ -32,7 +32,7 @@ export class MigrationLocalStorage { migration.azureAccount, migration.subscription, migration.migrationContext, - migration.sessionId! + migration.sessionId ?? undefinedSessionId ); migration.migrationContext.properties.sourceDatabaseName = sourceDatabase; migration.migrationContext.properties.backupConfiguration = backupConfiguration; @@ -41,7 +41,7 @@ export class MigrationLocalStorage { migration.azureAccount, migration.subscription, migration.asyncUrl, - migration.sessionId! + migration.sessionId ?? undefinedSessionId ); } }