Skip to content

Commit

Permalink
Support hot swapping between kernel finders (#12154)
Browse files Browse the repository at this point in the history
* Support hot swapping between kernel  finders

* oops

* Misc

* oops
  • Loading branch information
DonJayamanne authored Nov 24, 2022
1 parent 84d2c80 commit 47cc95a
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 171 deletions.
83 changes: 50 additions & 33 deletions src/kernels/raw/finder/contributedKerneFinder.node.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { EnvironmentType, PythonEnvironment } from '../../../platform/pythonEnvi
import { IPythonExtensionChecker } from '../../../platform/api/types';
import { PYTHON_LANGUAGE } from '../../../platform/common/constants';
import * as platform from '../../../platform/common/utils/platform';
import { CancellationTokenSource, EventEmitter, Memento, Uri } from 'vscode';
import { CancellationTokenSource, Disposable, EventEmitter, Memento, Uri } from 'vscode';
import {
IDisposable,
IExtensionContext,
Expand Down Expand Up @@ -71,6 +71,8 @@ import { ContributedLocalPythonEnvFinder } from './contributedLocalPythonEnvFind
import { takeTopRankKernel } from '../../../notebooks/controllers/kernelRanking/kernelRankingHelper.unit.test';
import { ITrustedKernelPaths } from './types';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPythonAndRelatedNonPythonKernelSpecFinder.old.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderWrapper } from './localPythonAndRelatedNonPythonKernelSpecFinder.wrapper.node';
import { ServiceContainer } from '../../../platform/ioc/container';

[false, true].forEach((isWindows) => {
(['Stable', 'Insiders'] as KernelPickerType[]).forEach((kernelPickerType) => {
Expand Down Expand Up @@ -279,59 +281,74 @@ import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPython
const featuresManager = mock<IFeaturesManager>();
when(featuresManager.features).thenReturn({ kernelPickerType });
kernelFinder = new KernelFinder(disposables);
const localPythonAndRelatedKernelFinder = new LocalPythonAndRelatedNonPythonKernelSpecFinder(
instance(interpreterService),
instance(fs),
instance(workspaceService),
jupyterPaths,
instance(extensionChecker),
nonPythonKernelSpecFinder,
instance(memento),
disposables,
instance(env),
instance(trustedKernels),
instance(featuresManager)

const serviceContainer = mock<ServiceContainer>();
const iocStub = sinon.stub(ServiceContainer, 'instance').get(() => instance(serviceContainer));
disposables.push(new Disposable(() => iocStub.restore()));
when(
serviceContainer.get<LocalPythonAndRelatedNonPythonKernelSpecFinder>(
LocalPythonAndRelatedNonPythonKernelSpecFinder
)
).thenCall(
() =>
new LocalPythonAndRelatedNonPythonKernelSpecFinder(
instance(interpreterService),
instance(fs),
instance(workspaceService),
jupyterPaths,
instance(extensionChecker),
nonPythonKernelSpecFinder,
instance(memento),
disposables,
instance(env),
instance(trustedKernels)
)
);
const localPythonAndRelatedKernelFinderOld = new LocalPythonAndRelatedNonPythonKernelSpecFinderOld(
instance(interpreterService),
instance(fs),
instance(workspaceService),
jupyterPaths,
instance(extensionChecker),
nonPythonKernelSpecFinder,
instance(memento),
when(
serviceContainer.get<LocalPythonAndRelatedNonPythonKernelSpecFinderOld>(
LocalPythonAndRelatedNonPythonKernelSpecFinderOld
)
).thenCall(
() =>
new LocalPythonAndRelatedNonPythonKernelSpecFinderOld(
instance(interpreterService),
instance(fs),
instance(workspaceService),
jupyterPaths,
instance(extensionChecker),
nonPythonKernelSpecFinder,
instance(memento),
disposables,
instance(env),
instance(trustedKernels)
)
);
const pythonKernelFinderWrapper = new LocalPythonAndRelatedNonPythonKernelSpecFinderWrapper(
disposables,
instance(env),
instance(trustedKernels),
instance(featuresManager)
);
const localKernelSpecFinder = new ContributedLocalKernelSpecFinder(
nonPythonKernelSpecFinder,
localPythonAndRelatedKernelFinder,
localPythonAndRelatedKernelFinderOld,
pythonKernelFinderWrapper,
kernelFinder,
[],
instance(extensionChecker),
instance(interpreterService),
instance(extensions),
instance(featuresManager)
instance(extensions)
);
const pythonEnvKernelFinder = new ContributedLocalPythonEnvFinder(
localPythonAndRelatedKernelFinder,
localPythonAndRelatedKernelFinderOld,
pythonKernelFinderWrapper,
kernelFinder,
[],
instance(extensionChecker),
instance(interpreterService),
instance(extensions),
instance(featuresManager)
instance(extensions)
);
changeEventFired = createEventHandler(kernelFinder, 'onDidChangeKernels', disposables);
localKernelSpecFinder.activate();
pythonEnvKernelFinder.activate();
nonPythonKernelSpecFinder.activate();
localPythonAndRelatedKernelFinder.activate();
localPythonAndRelatedKernelFinderOld.activate();
pythonKernelFinderWrapper.activate();

kernelRankHelper = new KernelRankingHelper(instance(preferredRemote));
}
Expand Down
20 changes: 6 additions & 14 deletions src/kernels/raw/finder/contributedLocalKernelSpecFinder.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
import { inject, injectable } from 'inversify';
import { EventEmitter } from 'vscode';
import { IKernelFinder, LocalKernelConnectionMetadata } from '../../types';
import { LocalPythonAndRelatedNonPythonKernelSpecFinder } from './localPythonAndRelatedNonPythonKernelSpecFinder.node';
import { LocalKnownPathKernelSpecFinder } from './localKnownPathKernelSpecFinder.node';
import { traceInfo, traceDecoratorError, traceError, traceVerbose } from '../../../platform/logging';
import { IDisposableRegistry, IExtensions, IFeaturesManager } from '../../../platform/common/types';
import { IDisposableRegistry, IExtensions } from '../../../platform/common/types';
import { capturePerfTelemetry, Telemetry } from '../../../telemetry';
import { areObjectsWithUrisTheSame, noop } from '../../../platform/common/utils/misc';
import { KernelFinder } from '../../kernelFinder';
Expand All @@ -22,7 +21,8 @@ import { PYTHON_LANGUAGE } from '../../../platform/common/constants';
import { PromiseMonitor } from '../../../platform/common/utils/promises';
import { getKernelRegistrationInfo } from '../../helpers';
import { createDeferred, Deferred } from '../../../platform/common/utils/async';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPythonAndRelatedNonPythonKernelSpecFinder.old.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderWrapper } from './localPythonAndRelatedNonPythonKernelSpecFinder.wrapper.node';
import { ILocalKernelFinder } from './localKernelSpecFinderBase.node';

// This class searches for local kernels.
// First it searches on a global persistent state, then on the installed python interpreters,
Expand Down Expand Up @@ -60,23 +60,15 @@ export class ContributedLocalKernelSpecFinder
private wasPythonInstalledWhenFetchingControllers = false;

private cache: LocalKernelConnectionMetadata[] = [];
private get pythonKernelFinder() {
return this.featuresManager.features.kernelPickerType === 'Insiders'
? this.pythonKernelFinderNew
: this.pythonKernelFinderOld;
}
constructor(
@inject(LocalKnownPathKernelSpecFinder) private readonly nonPythonKernelFinder: LocalKnownPathKernelSpecFinder,
@inject(LocalPythonAndRelatedNonPythonKernelSpecFinder)
private readonly pythonKernelFinderNew: LocalPythonAndRelatedNonPythonKernelSpecFinder,
@inject(LocalPythonAndRelatedNonPythonKernelSpecFinderOld)
private readonly pythonKernelFinderOld: LocalPythonAndRelatedNonPythonKernelSpecFinderOld,
@inject(LocalPythonAndRelatedNonPythonKernelSpecFinderWrapper)
private readonly pythonKernelFinder: ILocalKernelFinder<LocalKernelConnectionMetadata>,
@inject(IKernelFinder) kernelFinder: KernelFinder,
@inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry,
@inject(IPythonExtensionChecker) private readonly extensionChecker: IPythonExtensionChecker,
@inject(IInterpreterService) private readonly interpreters: IInterpreterService,
@inject(IExtensions) private readonly extensions: IExtensions,
@inject(IFeaturesManager) private readonly featuresManager: IFeaturesManager
@inject(IExtensions) private readonly extensions: IExtensions
) {
kernelFinder.registerKernelFinder(this);
this.disposables.push(this._onDidChangeStatus);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,17 @@ import { IDisposable, IExtensions, IFeaturesManager, KernelPickerType } from '..
import { IInterpreterService } from '../../../platform/interpreter/contracts';
import { createEventHandler } from '../../../test/common';
import { KernelFinder } from '../../kernelFinder';
import { LocalKernelSpecConnectionMetadata } from '../../types';
import { LocalKernelConnectionMetadata, LocalKernelSpecConnectionMetadata } from '../../types';
import { ContributedLocalKernelSpecFinder } from './contributedLocalKernelSpecFinder.node';
import { ILocalKernelFinder } from './localKernelSpecFinderBase.node';
import { LocalKnownPathKernelSpecFinder } from './localKnownPathKernelSpecFinder.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinder } from './localPythonAndRelatedNonPythonKernelSpecFinder.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPythonAndRelatedNonPythonKernelSpecFinder.old.node';

(['Stable', 'Insiders'] as KernelPickerType[]).forEach((kernelPickerType) => {
suite(`Contributed Local Kernel Spec Finder (Kernel Picker ${kernelPickerType})`, () => {
let finder: ContributedLocalKernelSpecFinder;
const disposables: IDisposable[] = [];
let nonPythonKernelFinder: LocalKnownPathKernelSpecFinder;
let pythonKernelFinder:
| LocalPythonAndRelatedNonPythonKernelSpecFinder
| LocalPythonAndRelatedNonPythonKernelSpecFinderOld;
let pythonKernelFinder: ILocalKernelFinder<LocalKernelConnectionMetadata>;
let kernelFinder: KernelFinder;
let extensionChecker: IPythonExtensionChecker;
let interpreterService: IInterpreterService;
Expand Down Expand Up @@ -57,9 +54,7 @@ import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPython
});
setup(() => {
nonPythonKernelFinder = mock<LocalKnownPathKernelSpecFinder>();
pythonKernelFinder = mock<
LocalPythonAndRelatedNonPythonKernelSpecFinder | LocalPythonAndRelatedNonPythonKernelSpecFinderOld
>();
pythonKernelFinder = mock<ILocalKernelFinder<LocalKernelConnectionMetadata>>();
kernelFinder = mock<KernelFinder>();
extensionChecker = mock<IPythonExtensionChecker>();
interpreterService = mock<IInterpreterService>();
Expand Down Expand Up @@ -87,14 +82,12 @@ import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPython
when(featureManager.features).thenReturn({ kernelPickerType });
finder = new ContributedLocalKernelSpecFinder(
instance(nonPythonKernelFinder),
instance(pythonKernelFinder) as LocalPythonAndRelatedNonPythonKernelSpecFinder,
instance(pythonKernelFinder) as LocalPythonAndRelatedNonPythonKernelSpecFinderOld,
instance(pythonKernelFinder),
instance(kernelFinder),
disposables,
instance(extensionChecker),
instance(interpreterService),
instance(extensions),
instance(featureManager)
instance(extensions)
);

clock = fakeTimers.install();
Expand Down
22 changes: 7 additions & 15 deletions src/kernels/raw/finder/contributedLocalPythonEnvFinder.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@

import { inject, injectable } from 'inversify';
import { EventEmitter } from 'vscode';
import { IKernelFinder, PythonKernelConnectionMetadata } from '../../../kernels/types';
import { LocalPythonAndRelatedNonPythonKernelSpecFinder } from './localPythonAndRelatedNonPythonKernelSpecFinder.node';
import { IKernelFinder, LocalKernelConnectionMetadata, PythonKernelConnectionMetadata } from '../../../kernels/types';
import { traceDecoratorError, traceError, traceVerbose } from '../../../platform/logging';
import { IDisposableRegistry, IExtensions, IFeaturesManager } from '../../../platform/common/types';
import { IDisposableRegistry, IExtensions } from '../../../platform/common/types';
import { capturePerfTelemetry, Telemetry } from '../../../telemetry';
import { areObjectsWithUrisTheSame, noop } from '../../../platform/common/utils/misc';
import { KernelFinder } from '../../kernelFinder';
Expand All @@ -20,7 +19,8 @@ import { ContributedKernelFinderKind, IContributedKernelFinder } from '../../int
import { createDeferred, Deferred } from '../../../platform/common/utils/async';
import { PromiseMonitor } from '../../../platform/common/utils/promises';
import { getKernelRegistrationInfo } from '../../helpers';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPythonAndRelatedNonPythonKernelSpecFinder.old.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderWrapper } from './localPythonAndRelatedNonPythonKernelSpecFinder.wrapper.node';
import { ILocalKernelFinder } from './localKernelSpecFinderBase.node';

// This class searches for local kernels.
// First it searches on a global persistent state, then on the installed python interpreters,
Expand Down Expand Up @@ -57,22 +57,14 @@ export class ContributedLocalPythonEnvFinder
private wasPythonInstalledWhenFetchingControllers = false;

private cache: PythonKernelConnectionMetadata[] = [];
private get pythonKernelFinder() {
return this.featuresManager.features.kernelPickerType === 'Insiders'
? this.pythonKernelFinderNew
: this.pythonKernelFinderOld;
}
constructor(
@inject(LocalPythonAndRelatedNonPythonKernelSpecFinder)
private readonly pythonKernelFinderNew: LocalPythonAndRelatedNonPythonKernelSpecFinder,
@inject(LocalPythonAndRelatedNonPythonKernelSpecFinderOld)
private readonly pythonKernelFinderOld: LocalPythonAndRelatedNonPythonKernelSpecFinderOld,
@inject(LocalPythonAndRelatedNonPythonKernelSpecFinderWrapper)
private readonly pythonKernelFinder: ILocalKernelFinder<LocalKernelConnectionMetadata>,
@inject(IKernelFinder) kernelFinder: KernelFinder,
@inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry,
@inject(IPythonExtensionChecker) private readonly extensionChecker: IPythonExtensionChecker,
@inject(IInterpreterService) private readonly interpreters: IInterpreterService,
@inject(IExtensions) private readonly extensions: IExtensions,
@inject(IFeaturesManager) private readonly featuresManager: IFeaturesManager
@inject(IExtensions) private readonly extensions: IExtensions
) {
kernelFinder.registerKernelFinder(this);
this.disposables.push(this.promiseMonitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ import { IDisposable, IExtensions, IFeaturesManager } from '../../../platform/co
import { IInterpreterService } from '../../../platform/interpreter/contracts';
import { createEventHandler } from '../../../test/common';
import { KernelFinder } from '../../kernelFinder';
import { LocalKernelSpecConnectionMetadata, PythonKernelConnectionMetadata } from '../../types';
import {
LocalKernelConnectionMetadata,
LocalKernelSpecConnectionMetadata,
PythonKernelConnectionMetadata
} from '../../types';
import { ContributedLocalPythonEnvFinder } from './contributedLocalPythonEnvFinder.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinder } from './localPythonAndRelatedNonPythonKernelSpecFinder.node';
import { LocalPythonAndRelatedNonPythonKernelSpecFinderOld } from './localPythonAndRelatedNonPythonKernelSpecFinder.old.node';
import { ILocalKernelFinder } from './localKernelSpecFinderBase.node';

suite('Contributed Python Kernel Finder', () => {
let finder: ContributedLocalPythonEnvFinder;
const disposables: IDisposable[] = [];
let pythonKernelFinder:
| LocalPythonAndRelatedNonPythonKernelSpecFinder
| LocalPythonAndRelatedNonPythonKernelSpecFinderOld;
let pythonKernelFinder: ILocalKernelFinder<LocalKernelConnectionMetadata>;
let kernelFinder: KernelFinder;
let extensionChecker: IPythonExtensionChecker;
let interpreterService: IInterpreterService;
Expand Down Expand Up @@ -71,9 +72,7 @@ suite('Contributed Python Kernel Finder', () => {
}
});
setup(() => {
pythonKernelFinder = mock<
LocalPythonAndRelatedNonPythonKernelSpecFinder | LocalPythonAndRelatedNonPythonKernelSpecFinderOld
>();
pythonKernelFinder = mock<ILocalKernelFinder<LocalKernelConnectionMetadata>>();
kernelFinder = mock<KernelFinder>();
extensionChecker = mock<IPythonExtensionChecker>();
interpreterService = mock<IInterpreterService>();
Expand All @@ -98,14 +97,12 @@ suite('Contributed Python Kernel Finder', () => {
const featuresManager = mock<IFeaturesManager>();
when(featuresManager.features).thenReturn({ kernelPickerType: 'Insiders' });
finder = new ContributedLocalPythonEnvFinder(
instance(pythonKernelFinder) as LocalPythonAndRelatedNonPythonKernelSpecFinder,
instance(pythonKernelFinder) as LocalPythonAndRelatedNonPythonKernelSpecFinderOld,
instance(pythonKernelFinder),
instance(kernelFinder),
disposables,
instance(extensionChecker),
instance(interpreterService),
instance(extensions),
instance(featuresManager)
instance(extensions)
);

clock = fakeTimers.install();
Expand Down
Loading

0 comments on commit 47cc95a

Please sign in to comment.