diff --git a/src/controllers/ExtensionController.ts b/src/controllers/ExtensionController.ts index c057b438..55f28d52 100644 --- a/src/controllers/ExtensionController.ts +++ b/src/controllers/ExtensionController.ts @@ -345,7 +345,10 @@ export class ExtensionController implements Disposable { }; this._coreClientCache = new URLMap(); + this._context.subscriptions.push(this._coreClientCache); + this._dheClientCache = new URLMap(); + this._context.subscriptions.push(this._dheClientCache); this._panelService = new PanelService(); this._context.subscriptions.push(this._panelService); diff --git a/src/services/DheService.ts b/src/services/DheService.ts index 50dafde2..dc5e805a 100644 --- a/src/services/DheService.ts +++ b/src/services/DheService.ts @@ -256,8 +256,10 @@ export class DheService implements IDheService { const querySerials = [...this._querySerialSet]; this._querySerialSet.clear(); - this._workerInfoMap.clear(); - await this._disposeQueries(querySerials); + await Promise.all([ + this._workerInfoMap.dispose(), + this._disposeQueries(querySerials), + ]); }; } diff --git a/src/services/PanelService.ts b/src/services/PanelService.ts index 30bd67bf..42b6036b 100644 --- a/src/services/PanelService.ts +++ b/src/services/PanelService.ts @@ -35,9 +35,12 @@ export class PanelService implements IPanelService, Disposable { * Cleanup resources. */ dispose = async (): Promise => { - this._cnPanelMap.clear(); - this._cnVariableMap.clear(); this._onDidUpdate.dispose(); + + await Promise.all([ + this._cnPanelMap.dispose(), + this._cnVariableMap.dispose(), + ]); }; /** diff --git a/src/services/SerializedKeyMap.ts b/src/services/SerializedKeyMap.ts index cb291664..e097583a 100644 --- a/src/services/SerializedKeyMap.ts +++ b/src/services/SerializedKeyMap.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode'; import type { Disposable } from '../types'; +import { isDisposable } from '../util'; /** * Base class for Maps that need to store their keys as serialized string values @@ -42,8 +43,20 @@ export abstract class SerializedKeyMap implements Disposable { } dispose = async (): Promise => { - this._map.clear(); this._onDidChange.dispose(); + + const promises = [...this._map.values()]; + this._map.clear(); + + const disposing = promises.map(async maybePromise => { + // If value is a Promise, it has to be resolved before it can be disposed. + const resolved = await maybePromise; + if (isDisposable(resolved)) { + await resolved.dispose(); + } + }); + + await Promise.all(disposing); }; get(key: TKey): TValue | undefined { diff --git a/src/services/ServerManager.ts b/src/services/ServerManager.ts index 53d4f6dd..a87ebc9b 100644 --- a/src/services/ServerManager.ts +++ b/src/services/ServerManager.ts @@ -100,14 +100,21 @@ export class ServerManager implements IServerManager { canStartServer: boolean; - async dispose(): Promise { + dispose = async (): Promise => { this._onDidConnect.dispose(); this._onDidDisconnect.dispose(); this._onDidLoadConfig.dispose(); this._onDidServerStatusChange.dispose(); this._onDidRegisterEditor.dispose(); this._onDidUpdate.dispose(); - } + + await Promise.all([ + this._connectionMap.dispose(), + this._serverMap.dispose(), + this._uriConnectionsMap.dispose(), + this._workerURLToServerURLMap.dispose(), + ]); + }; loadServerConfig = async (): Promise => { // We want to keep any existing managed servers that aren't overridden by @@ -243,6 +250,7 @@ export class ServerManager implements IServerManager { this._onDidUpdate.fire(); if (!(await connection.initSession())) { + connection.dispose(); this._connectionMap.delete(serverUrl); return null; } diff --git a/src/services/cache/ByURLAsyncCache.ts b/src/services/cache/ByURLAsyncCache.ts index 64f10c92..8f230a54 100644 --- a/src/services/cache/ByURLAsyncCache.ts +++ b/src/services/cache/ByURLAsyncCache.ts @@ -1,6 +1,5 @@ import * as vscode from 'vscode'; import type { IAsyncCacheService } from '../../types'; -import { isDisposable } from '../../util'; import { URLMap } from '../URLMap'; /** @@ -37,18 +36,6 @@ export class ByURLAsyncCache dispose = async (): Promise => { this._onDidInvalidate.dispose(); - - const promises = [...this._promiseMap.values()]; - this._promiseMap.clear(); - - // Values have to be resolved before they can be disposed. - const disposing = promises.map(async promise => { - const resolved = await promise; - if (isDisposable(resolved)) { - await resolved.dispose(); - } - }); - - await Promise.all(disposing); + await this._promiseMap.dispose(); }; }