Skip to content
Closed
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
6 changes: 5 additions & 1 deletion src/client/datascience/jupyter/jupyterSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { noop } from '../../common/utils/misc';
import { IConnection, IJupyterKernel, IJupyterKernelSpec, IJupyterSession } from '../types';
import { JupyterWaitForIdleError } from './jupyterWaitForIdleError';
import { JupyterKernelPromiseFailedError } from './kernels/jupyterKernelPromiseFailedError';
import { KernelSelector } from './kernels/kernelSelector';

export class JupyterSession implements IJupyterSession {
private session: Session.ISession | undefined;
Expand All @@ -31,7 +32,8 @@ export class JupyterSession implements IJupyterSession {
private serverSettings: ServerConnection.ISettings,
private kernelSpec: IJupyterKernelSpec | IJupyterKernel & Partial<IJupyterKernelSpec> | undefined,
private sessionManager: SessionManager,
private contentsManager: ContentsManager
private contentsManager: ContentsManager,
private readonly kernelSelector: KernelSelector
) {
this.statusHandler = this.onStatusChanged.bind(this);
}
Expand Down Expand Up @@ -101,6 +103,7 @@ export class JupyterSession implements IJupyterSession {
if (!this.session) {
throw new Error(localize.DataScience.sessionDisposed());
}
this.kernelSelector.removeKernelFromIgnoreList(this.session.kernel);
traceInfo(`Got new session ${this.session.kernel.id}`);

// Rewire our status changed event.
Expand Down Expand Up @@ -261,6 +264,7 @@ export class JupyterSession implements IJupyterSession {
while (tryCount < 3) {
try {
result = await this.createSession(serverSettings, contentsManager, cancelToken);
this.kernelSelector.addKernelToIgnoreList(result.kernel);
await this.waitForIdleOnSession(result, 30000);
return result;
} catch (exc) {
Expand Down
6 changes: 4 additions & 2 deletions src/client/datascience/jupyter/jupyterSessionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { JupyterSession } from './jupyterSession';
import { createJupyterWebSocket } from './jupyterWebSocket';
import { JupyterKernelSpec } from './kernels/jupyterKernelSpec';
import { KernelSelector } from './kernels/kernelSelector';

export class JupyterSessionManager implements IJupyterSessionManager {

Expand All @@ -31,7 +32,8 @@ export class JupyterSessionManager implements IJupyterSessionManager {
constructor(
private jupyterPasswordConnect: IJupyterPasswordConnect,
private config: IConfigurationService,
private failOnPassword: boolean | undefined
private failOnPassword: boolean | undefined,
private kernelSelector: KernelSelector
) {
}

Expand Down Expand Up @@ -85,7 +87,7 @@ export class JupyterSessionManager implements IJupyterSessionManager {
throw new Error(localize.DataScience.sessionDisposed());
}
// Create a new session and attempt to connect to it
const session = new JupyterSession(this.connInfo, this.serverSettings, kernelSpec, this.sessionManager, this.contentsManager);
const session = new JupyterSession(this.connInfo, this.serverSettings, kernelSpec, this.sessionManager, this.contentsManager, this.kernelSelector);
try {
await session.connect(cancelToken);
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { inject, injectable } from 'inversify';
import { IConfigurationService } from '../../common/types';
import { IConnection, IJupyterPasswordConnect, IJupyterSessionManager, IJupyterSessionManagerFactory } from '../types';
import { JupyterSessionManager } from './jupyterSessionManager';
import { KernelSelector } from './kernels/kernelSelector';

@injectable()
export class JupyterSessionManagerFactory implements IJupyterSessionManagerFactory {

constructor(
@inject(IJupyterPasswordConnect) private jupyterPasswordConnect: IJupyterPasswordConnect,
@inject(IConfigurationService) private config: IConfigurationService
@inject(IConfigurationService) private config: IConfigurationService,
@inject(KernelSelector) private kernelSelector: KernelSelector
) {
}

Expand All @@ -22,7 +24,7 @@ export class JupyterSessionManagerFactory implements IJupyterSessionManagerFacto
* @param failOnPassword - whether or not to fail the creation if a password is required.
*/
public async create(connInfo: IConnection, failOnPassword?: boolean): Promise<IJupyterSessionManager> {
const result = new JupyterSessionManager(this.jupyterPasswordConnect, this.config, failOnPassword);
const result = new JupyterSessionManager(this.jupyterPasswordConnect, this.config, failOnPassword, this.kernelSelector);
await result.initialize(connInfo);
return result;
}
Expand Down
37 changes: 35 additions & 2 deletions src/client/datascience/jupyter/kernels/kernelSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
'use strict';

import { nbformat } from '@jupyterlab/coreutils';
import { Kernel } from '@jupyterlab/services';
import { inject, injectable } from 'inversify';
import { CancellationToken } from 'vscode-jsonrpc';
import { IApplicationShell } from '../../../common/application/types';
Expand Down Expand Up @@ -41,13 +42,43 @@ export type KernelSpecInterpreter = {

@injectable()
export class KernelSelector {
/**
* List of ids of kernels that should be hiddenn from the kernel picker.
*
* @private
* @type {new Set<string>}
* @memberof KernelSelector
*/
private readonly kernelIdsToHide = new Set<string>();
constructor(
@inject(KernelSelectionProvider) private readonly selectionProvider: KernelSelectionProvider,
@inject(IApplicationShell) private readonly applicationShell: IApplicationShell,
@inject(KernelService) private readonly kernelService: KernelService,
@inject(IInterpreterService) private readonly interpreterService: IInterpreterService,
@inject(IInstaller) private readonly installer: IInstaller
) {}

/**
* Ensure kernels such as those associated with the restart session are not displayed in the kernel picker.
*
* @param {Kernel.IKernelConnection} kernel
* @memberof KernelSelector
*/
public addKernelToIgnoreList(kernel: Kernel.IKernelConnection): void {
this.kernelIdsToHide.add(kernel.id);
this.kernelIdsToHide.add(kernel.clientId);
}
/**
* Opposite of the add counterpart.
*
* @param {Kernel.IKernelConnection} kernel
* @memberof KernelSelector
*/
public removeKernelFromIgnoreList(kernel: Kernel.IKernelConnection): void {
this.kernelIdsToHide.delete(kernel.id);
this.kernelIdsToHide.delete(kernel.clientId);
}

/**
* Selects a kernel from a remote session.
*
Expand All @@ -57,7 +88,8 @@ export class KernelSelector {
* @memberof KernelSelector
*/
public async selectRemoteKernel(session: IJupyterSessionManager, cancelToken?: CancellationToken): Promise<KernelSpecInterpreter> {
const suggestions = await this.selectionProvider.getKernelSelectionsForRemoteSession(session, cancelToken);
let suggestions = await this.selectionProvider.getKernelSelectionsForRemoteSession(session, cancelToken);
suggestions = suggestions.filter(item => item.selection.kernelModel?.id ? this.kernelIdsToHide.has(item.selection.kernelModel?.id) : true);
return this.selectKernel(suggestions, session, cancelToken);
}
/**
Expand All @@ -69,7 +101,8 @@ export class KernelSelector {
* @memberof KernelSelector
*/
public async selectLocalKernel(session?: IJupyterSessionManager, cancelToken?: CancellationToken): Promise<KernelSpecInterpreter> {
const suggestions = await this.selectionProvider.getKernelSelectionsForLocalSession(session, cancelToken);
let suggestions = await this.selectionProvider.getKernelSelectionsForLocalSession(session, cancelToken);
suggestions = suggestions.filter(item => item.selection.kernelModel?.id ? this.kernelIdsToHide.has(item.selection.kernelModel?.id) : true);
return this.selectKernel(suggestions, session, cancelToken);
}
/**
Expand Down