-
Notifications
You must be signed in to change notification settings - Fork 300
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
Merge remote kernel finders. #11879
Merge remote kernel finders. #11879
Changes from 3 commits
2b3f5d5
489327c
b00aac5
c941fd3
5fa6004
b9a02b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,6 @@ import { | |
import { IInterpreterService } from '../../../platform/interpreter/contracts'; | ||
import { JupyterSessionManager } from '../session/jupyterSessionManager'; | ||
import { JupyterSessionManagerFactory } from '../session/jupyterSessionManagerFactory'; | ||
import { RemoteKernelFinder } from './remoteKernelFinder'; | ||
import { ILocalKernelFinder } from '../../raw/types'; | ||
import { ActiveKernelIdList, PreferredRemoteKernelIdProvider } from '../preferredRemoteKernelIdProvider'; | ||
import { | ||
|
@@ -46,11 +45,12 @@ import { KernelRankingHelper } from '../../../notebooks/controllers/kernelRankin | |
import { IExtensions } from '../../../platform/common/types'; | ||
import { takeTopRankKernel } from '../../raw/finder/localKernelFinder.unit.test'; | ||
import { createEventHandler, TestEventHandler } from '../../../test/common'; | ||
import { UniversalRemoteKernelFinder } from './universalRemoteKernelFinder'; | ||
|
||
suite(`Remote Kernel Finder`, () => { | ||
let disposables: Disposable[] = []; | ||
let preferredRemoteKernelIdProvider: PreferredRemoteKernelIdProvider; | ||
let remoteKernelFinder: RemoteKernelFinder; | ||
let remoteKernelFinder: UniversalRemoteKernelFinder; | ||
let localKernelFinder: ILocalKernelFinder; | ||
let kernelFinder: KernelFinder; | ||
let kernelRankHelper: IKernelRankingHelper; | ||
|
@@ -175,21 +175,22 @@ suite(`Remote Kernel Finder`, () => { | |
disposables.push(kernelsChanged); | ||
kernelRankHelper = new KernelRankingHelper(preferredRemoteKernelIdProvider); | ||
|
||
remoteKernelFinder = new RemoteKernelFinder( | ||
remoteKernelFinder = new UniversalRemoteKernelFinder( | ||
'currentremote', | ||
'Local Kernels', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't look correct here, plus the string should be localized if it's a display name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @IanMatthewHuff it's a test so I didn't try to make it localized. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rebornix was reading too fast. You are totally right :) |
||
RemoteKernelSpecsCacheKey, | ||
instance(jupyterSessionManagerFactory), | ||
instance(interpreterService), | ||
instance(extensionChecker), | ||
instance(notebookProvider), | ||
instance(serverUriStorage), | ||
instance(connectionType), | ||
instance(memento), | ||
instance(env), | ||
instance(cachedRemoteKernelValidator), | ||
kernelFinder, | ||
[], | ||
instance(kernelProvider), | ||
instance(extensions), | ||
false | ||
false, | ||
serverEntry | ||
); | ||
remoteKernelFinder.activate().then(noop, noop); | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ import { Memento } from 'vscode'; | |
import { IKernelFinder, IKernelProvider, INotebookProvider } from '../../types'; | ||
import { | ||
GLOBAL_MEMENTO, | ||
IConfigurationService, | ||
IDisposableRegistry, | ||
IExtensions, | ||
IMemento, | ||
|
@@ -26,30 +27,36 @@ import { IApplicationEnvironment } from '../../../platform/common/application/ty | |
import { KernelFinder } from '../../kernelFinder'; | ||
import { IExtensionSingleActivationService } from '../../../platform/activation/types'; | ||
import { UniversalRemoteKernelFinder } from './universalRemoteKernelFinder'; | ||
import { ContributedKernelFinderKind } from '../../internalTypes'; | ||
import * as localize from '../../../platform/common/utils/localize'; | ||
import { RemoteKernelSpecsCacheKey } from '../../common/commonFinder'; | ||
|
||
// This class creates RemoteKernelFinders for all registered Jupyter Server URIs | ||
@injectable() | ||
export class UniversalRemoteKernelFinderController implements IExtensionSingleActivationService { | ||
/** Strategy design */ | ||
interface IRemoteKernelFinderRegistrationStrategy { | ||
activate(): Promise<void>; | ||
dispose(): void; | ||
} | ||
|
||
class MultiServerStrategy implements IRemoteKernelFinderRegistrationStrategy { | ||
private serverFinderMapping: Map<string, UniversalRemoteKernelFinder> = new Map< | ||
string, | ||
UniversalRemoteKernelFinder | ||
>(); | ||
|
||
constructor( | ||
@inject(IJupyterSessionManagerFactory) private jupyterSessionManagerFactory: IJupyterSessionManagerFactory, | ||
@inject(IInterpreterService) private interpreterService: IInterpreterService, | ||
@inject(IPythonExtensionChecker) private extensionChecker: IPythonExtensionChecker, | ||
@inject(INotebookProvider) private readonly notebookProvider: INotebookProvider, | ||
@inject(IJupyterServerUriStorage) private readonly serverUriStorage: IJupyterServerUriStorage, | ||
@inject(IMemento) @named(GLOBAL_MEMENTO) private readonly globalState: Memento, | ||
@inject(IApplicationEnvironment) private readonly env: IApplicationEnvironment, | ||
@inject(IJupyterRemoteCachedKernelValidator) | ||
private jupyterSessionManagerFactory: IJupyterSessionManagerFactory, | ||
private interpreterService: IInterpreterService, | ||
private extensionChecker: IPythonExtensionChecker, | ||
private readonly notebookProvider: INotebookProvider, | ||
private readonly serverUriStorage: IJupyterServerUriStorage, | ||
private readonly globalState: Memento, | ||
private readonly env: IApplicationEnvironment, | ||
private readonly cachedRemoteKernelValidator: IJupyterRemoteCachedKernelValidator, | ||
@inject(IKernelFinder) private readonly kernelFinder: KernelFinder, | ||
@inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry, | ||
@inject(IKernelProvider) private readonly kernelProvider: IKernelProvider, | ||
@inject(IExtensions) private readonly extensions: IExtensions, | ||
@inject(IsWebExtension) private isWebExtension: boolean | ||
private readonly kernelFinder: KernelFinder, | ||
private readonly disposables: IDisposableRegistry, | ||
private readonly kernelProvider: IKernelProvider, | ||
private readonly extensions: IExtensions, | ||
private isWebExtension: boolean | ||
) {} | ||
|
||
async activate(): Promise<void> { | ||
|
@@ -66,11 +73,17 @@ export class UniversalRemoteKernelFinderController implements IExtensionSingleAc | |
|
||
createRemoteKernelFinder(serverUri: IJupyterServerUriEntry) { | ||
if (!serverUri.isValidated) { | ||
// TODO@rebornix, what if it's now validated? | ||
return; | ||
} | ||
|
||
if (!this.serverFinderMapping.has(serverUri.serverId)) { | ||
const finder = new UniversalRemoteKernelFinder( | ||
`${ContributedKernelFinderKind.Remote}-${serverUri.serverId}`, | ||
localize.DataScience.universalRemoteKernelFinderDisplayName().format( | ||
serverUri.displayName || serverUri.uri | ||
), | ||
`${RemoteKernelSpecsCacheKey}-${serverUri.serverId}`, | ||
this.jupyterSessionManagerFactory, | ||
this.interpreterService, | ||
this.extensionChecker, | ||
|
@@ -100,4 +113,158 @@ export class UniversalRemoteKernelFinderController implements IExtensionSingleAc | |
this.serverFinderMapping.delete(uri.serverId); | ||
}); | ||
} | ||
|
||
dispose() { | ||
this.serverFinderMapping.forEach((finder) => finder.dispose()); | ||
} | ||
} | ||
|
||
class SingleServerStrategy implements IRemoteKernelFinderRegistrationStrategy { | ||
private _activeServerFinder: { entry: IJupyterServerUriEntry; finder: UniversalRemoteKernelFinder } | undefined; | ||
constructor( | ||
private jupyterSessionManagerFactory: IJupyterSessionManagerFactory, | ||
private interpreterService: IInterpreterService, | ||
private extensionChecker: IPythonExtensionChecker, | ||
private readonly notebookProvider: INotebookProvider, | ||
private readonly serverUriStorage: IJupyterServerUriStorage, | ||
private readonly globalState: Memento, | ||
private readonly env: IApplicationEnvironment, | ||
private readonly cachedRemoteKernelValidator: IJupyterRemoteCachedKernelValidator, | ||
private readonly kernelFinder: KernelFinder, | ||
private readonly disposables: IDisposableRegistry, | ||
private readonly kernelProvider: IKernelProvider, | ||
private readonly extensions: IExtensions, | ||
private isWebExtension: boolean | ||
) {} | ||
|
||
async activate(): Promise<void> { | ||
this.disposables.push( | ||
this.serverUriStorage.onDidChangeUri(() => { | ||
this.updateRemoteKernelFinder().then(noop, noop); | ||
}) | ||
); | ||
|
||
this.updateRemoteKernelFinder().then(noop, noop); | ||
} | ||
|
||
async updateRemoteKernelFinder() { | ||
if (this.serverUriStorage.isLocalLaunch) { | ||
// no remote kernel finder needed | ||
this._activeServerFinder?.finder.dispose(); | ||
this._activeServerFinder = undefined; | ||
return; | ||
} | ||
|
||
const uri = await this.serverUriStorage.getRemoteUri(); | ||
// uri should not be local | ||
|
||
if (!uri || !uri.isValidated) { | ||
this._activeServerFinder?.finder.dispose(); | ||
this._activeServerFinder = undefined; | ||
return; | ||
} | ||
|
||
if (this._activeServerFinder?.entry.serverId === uri.serverId) { | ||
// no op | ||
return; | ||
} | ||
|
||
this._activeServerFinder?.finder.dispose(); | ||
const finder = new UniversalRemoteKernelFinder( | ||
'currentremote', | ||
localize.DataScience.remoteKernelFinderDisplayName(), | ||
RemoteKernelSpecsCacheKey, | ||
this.jupyterSessionManagerFactory, | ||
this.interpreterService, | ||
this.extensionChecker, | ||
this.notebookProvider, | ||
this.globalState, | ||
this.env, | ||
this.cachedRemoteKernelValidator, | ||
this.kernelFinder, | ||
this.kernelProvider, | ||
this.extensions, | ||
this.isWebExtension, | ||
uri | ||
); | ||
|
||
this._activeServerFinder = { | ||
entry: uri, | ||
finder | ||
}; | ||
|
||
finder.activate().then(noop, noop); | ||
} | ||
|
||
dispose() { | ||
this._activeServerFinder?.finder.dispose(); | ||
} | ||
} | ||
|
||
// This class creates RemoteKernelFinders for all registered Jupyter Server URIs | ||
@injectable() | ||
export class UniversalRemoteKernelFinderController implements IExtensionSingleActivationService { | ||
private _strategy: IRemoteKernelFinderRegistrationStrategy; | ||
|
||
constructor( | ||
@inject(IConfigurationService) readonly configurationService: IConfigurationService, | ||
@inject(IJupyterSessionManagerFactory) | ||
private readonly jupyterSessionManagerFactory: IJupyterSessionManagerFactory, | ||
@inject(IInterpreterService) private readonly interpreterService: IInterpreterService, | ||
@inject(IPythonExtensionChecker) private readonly extensionChecker: IPythonExtensionChecker, | ||
@inject(INotebookProvider) private readonly notebookProvider: INotebookProvider, | ||
@inject(IJupyterServerUriStorage) private readonly serverUriStorage: IJupyterServerUriStorage, | ||
@inject(IMemento) @named(GLOBAL_MEMENTO) private readonly globalState: Memento, | ||
@inject(IApplicationEnvironment) private readonly env: IApplicationEnvironment, | ||
@inject(IJupyterRemoteCachedKernelValidator) | ||
private readonly cachedRemoteKernelValidator: IJupyterRemoteCachedKernelValidator, | ||
@inject(IKernelFinder) private readonly kernelFinder: KernelFinder, | ||
@inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry, | ||
@inject(IKernelProvider) private readonly kernelProvider: IKernelProvider, | ||
@inject(IExtensions) private readonly extensions: IExtensions, | ||
@inject(IsWebExtension) private readonly isWebExtension: boolean | ||
) { | ||
this._strategy = this.getStrategy(); | ||
this.disposables.push(this._strategy); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weird that there is no |
||
} | ||
|
||
private getStrategy(): IRemoteKernelFinderRegistrationStrategy { | ||
if (this.configurationService.getSettings().kernelPickerType === 'Insiders') { | ||
return new MultiServerStrategy( | ||
this.jupyterSessionManagerFactory, | ||
this.interpreterService, | ||
this.extensionChecker, | ||
this.notebookProvider, | ||
this.serverUriStorage, | ||
this.globalState, | ||
this.env, | ||
this.cachedRemoteKernelValidator, | ||
this.kernelFinder, | ||
this.disposables, | ||
this.kernelProvider, | ||
this.extensions, | ||
this.isWebExtension | ||
); | ||
} else { | ||
return new SingleServerStrategy( | ||
this.jupyterSessionManagerFactory, | ||
this.interpreterService, | ||
this.extensionChecker, | ||
this.notebookProvider, | ||
this.serverUriStorage, | ||
this.globalState, | ||
this.env, | ||
this.cachedRemoteKernelValidator, | ||
this.kernelFinder, | ||
this.disposables, | ||
this.kernelProvider, | ||
this.extensions, | ||
this.isWebExtension | ||
); | ||
} | ||
} | ||
|
||
async activate(): Promise<void> { | ||
this._strategy.activate().then(noop, noop); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,9 @@ export class JupyterServerUriStorage implements IJupyterServerUriStorage, IServe | |
public get onDidChange(): Event<void> { | ||
return this._onDidChangeUri.event; | ||
} | ||
public get onDidChangeConnectionType(): Event<void> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's duplicate but intentional. We want to get rid of |
||
return this._onDidChangeUri.event; | ||
} | ||
public get isLocalLaunch(): boolean { | ||
return this._localOnly; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the very end, we will drop the prefix
Universal
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, don't think that was a great name in the first place 😆 . Just needed something to distinguish it.