Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notify providers when deleting Server Uri from MRU #13719

Merged
merged 3 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 36 additions & 14 deletions src/kernels/jupyter/connection/jupyterUriProviderRegistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,29 @@ import * as localize from '../../../platform/common/utils/localize';
import { noop } from '../../../platform/common/utils/misc';
import { InvalidRemoteJupyterServerUriHandleError } from '../../errors/invalidRemoteJupyterServerUriHandleError';
import { computeServerId, generateUriFromRemoteProvider } from '../jupyterUtils';
import { IInternalJupyterUriProvider, IJupyterUriProviderRegistration } from '../types';
import {
IInternalJupyterUriProvider,
IJupyterServerUriEntry,
IJupyterServerUriStorage,
IJupyterUriProviderRegistration
} from '../types';
import { sendTelemetryEvent } from '../../../telemetry';
import { traceError } from '../../../platform/logging';
import { IJupyterServerUri, IJupyterUriProvider, JupyterServerUriHandle } from '../../../api';
import { Disposables } from '../../../platform/common/utils';
import { IServiceContainer } from '../../../platform/ioc/types';
import { IExtensionSyncActivationService } from '../../../platform/activation/types';

const REGISTRATION_ID_EXTENSION_OWNER_MEMENTO_KEY = 'REGISTRATION_ID_EXTENSION_OWNER_MEMENTO_KEY';
export const REGISTRATION_ID_EXTENSION_OWNER_MEMENTO_KEY = 'REGISTRATION_ID_EXTENSION_OWNER_MEMENTO_KEY';

/**
* Handles registration of 3rd party URI providers.
*/
@injectable()
export class JupyterUriProviderRegistration implements IJupyterUriProviderRegistration {
export class JupyterUriProviderRegistration
extends Disposables
implements IJupyterUriProviderRegistration, IExtensionSyncActivationService
{
private readonly _onProvidersChanged = new EventEmitter<void>();
private loadedOtherExtensionsPromise: Promise<void> | undefined;
private _providers = new Map<string, JupyterUriProviderWrapper>();
Expand All @@ -35,19 +45,19 @@ export class JupyterUriProviderRegistration implements IJupyterUriProviderRegist
constructor(
@inject(IExtensions) private readonly extensions: IExtensions,
@inject(IDisposableRegistry) disposables: IDisposableRegistry,
@inject(IMemento) @named(GLOBAL_MEMENTO) private readonly globalMemento: Memento
@inject(IMemento) @named(GLOBAL_MEMENTO) private readonly globalMemento: Memento,
@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer
) {
disposables.push(this._onProvidersChanged);
disposables.push(new Disposable(() => this._providers.forEach((p) => p.dispose())));
super();
disposables.push(this);
this.disposables.push(this._onProvidersChanged);
this.disposables.push(new Disposable(() => this._providers.forEach((p) => p.dispose())));
}

public async getProviders(): Promise<ReadonlyArray<IInternalJupyterUriProvider>> {
await this.loadOtherExtensions();

// Other extensions should have registered in their activate callback
return Array.from(this.providers.values());
public activate(): void {
const serverStorage = this.serviceContainer.get<IJupyterServerUriStorage>(IJupyterServerUriStorage);
this.disposables.push(serverStorage.onDidRemove(this.onDidRemoveServer, this));
}

public async getProvider(id: string): Promise<IInternalJupyterUriProvider | undefined> {
await this.loadOtherExtensions();
if (!this._providers.has(id)) {
Expand All @@ -69,17 +79,18 @@ export class JupyterUriProviderRegistration implements IJupyterUriProviderRegist
}
this._onProvidersChanged.fire();

return {
const disposable = {
dispose: () => {
this._providers.get(provider.id)?.dispose();
this._providers.delete(provider.id);
this._onProvidersChanged.fire();
}
};
this.disposables.push(disposable);
return disposable;
}
public async getJupyterServerUri(id: string, handle: JupyterServerUriHandle): Promise<IJupyterServerUri> {
await this.loadOtherExtensions();

const provider = this._providers.get(id);
if (!provider) {
traceError(`${localize.DataScience.unknownServerUri}. Provider Id=${id} and handle=${handle}`);
Expand All @@ -96,6 +107,17 @@ export class JupyterUriProviderRegistration implements IJupyterUriProviderRegist
return provider.getServerUri(handle);
}

private onDidRemoveServer(e: IJupyterServerUriEntry[]) {
Promise.all(
e.map(async (s) => {
const provider = await this.getProvider(s.provider.id).catch(noop);
if (!provider || !provider.removeHandle) {
return;
}
await provider.removeHandle(s.provider.handle).catch(noop);
})
).catch(noop);
}
private loadOtherExtensions(): Promise<void> {
if (!this.loadedOtherExtensionsPromise) {
this.loadedOtherExtensionsPromise = this.loadOtherExtensionsImpl();
Expand Down
Loading