Skip to content

Commit 48797c5

Browse files
authored
Ensure we do not switch kernel if already the same (#13297)
1 parent ddbea64 commit 48797c5

File tree

6 files changed

+27
-12
lines changed

6 files changed

+27
-12
lines changed

src/client/datascience/jupyter/kernels/kernel.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export class Kernel implements IKernel {
3232
if (this._notebook) {
3333
return this._notebook.getKernelSpec();
3434
}
35-
return this._metadata.kernelSpec || this._metadata.kernelModel;
35+
return this.metadata.kernelSpec || this.metadata.kernelModel;
3636
}
3737
get onStatusChanged(): Event<ServerStatus> {
3838
return this._onStatusChanged.event;
@@ -63,7 +63,7 @@ export class Kernel implements IKernel {
6363
private restarting?: Deferred<void>;
6464
constructor(
6565
public readonly uri: Uri,
66-
private readonly _metadata: KernelSelection,
66+
public readonly metadata: Readonly<KernelSelection>,
6767
private readonly notebookProvider: INotebookProvider,
6868
private readonly disposables: IDisposableRegistry,
6969
private readonly waitForIdleTimeoutMs: number,
@@ -93,8 +93,8 @@ export class Kernel implements IKernel {
9393
const metadata = ((getDefaultNotebookContent().metadata || {}) as unknown) as nbformat.INotebookMetadata;
9494
updateNotebookMetadata(
9595
metadata,
96-
this._metadata.interpreter,
97-
this._metadata.kernelSpec || this._metadata.kernelModel
96+
this.metadata.interpreter,
97+
this.metadata.kernelSpec || this.metadata.kernelModel
9898
);
9999

100100
this._notebookPromise = this.notebookProvider.getOrCreateNotebook({

src/client/datascience/jupyter/kernels/kernelProvider.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
'use strict';
55

6+
import * as fastDeepEqual from 'fast-deep-equal';
67
import { inject, injectable } from 'inversify';
78
import { Uri } from 'vscode';
89
import { traceWarning } from '../../../common/logger';
@@ -25,10 +26,7 @@ export class KernelProvider {
2526
}
2627
public getOrCreate(uri: Uri, options: KernelOptions): IKernel | undefined {
2728
const existingKernelInfo = this.kernelsByUri.get(uri.toString());
28-
if (
29-
existingKernelInfo &&
30-
JSON.stringify(existingKernelInfo.options.metadata) === JSON.stringify(options.metadata)
31-
) {
29+
if (existingKernelInfo && fastDeepEqual(existingKernelInfo.options.metadata, options.metadata)) {
3230
return existingKernelInfo.kernel;
3331
}
3432

src/client/datascience/jupyter/kernels/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export interface IKernelSelectionUsage {
5757
export interface IKernel extends IAsyncDisposable {
5858
readonly uri: Uri;
5959
readonly kernelSpec?: IJupyterKernelSpec | LiveKernelModel;
60+
readonly metadata: Readonly<KernelSelection>;
6061
readonly onStatusChanged: Event<ServerStatus>;
6162
readonly onDisposed: Event<void>;
6263
readonly onRestarted: Event<void>;

src/client/datascience/notebook/helpers/executionHelpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import type { nbformat } from '@jupyterlab/coreutils';
77
import type { KernelMessage } from '@jupyterlab/services';
8+
import * as fastDeepEqual from 'fast-deep-equal';
89
import { NotebookCell, NotebookCellRunState, NotebookDocument } from 'vscode';
910
import { createErrorOutput } from '../../../../datascience-ui/common/cellFactory';
1011
import { createIOutputFromCellOutputs, createVSCCellOutputsFromOutputs, translateErrorOutput } from './helpers';
@@ -106,7 +107,7 @@ export function updateCellOutput(vscCell: NotebookCell, outputs: nbformat.IOutpu
106107
}
107108
// Compare outputs (at the end of the day everything is serializable).
108109
// Hence this is a safe comparison.
109-
if (vscCell.outputs.length === newOutput.length && JSON.stringify(vscCell.outputs) === JSON.stringify(newOutput)) {
110+
if (vscCell.outputs.length === newOutput.length && fastDeepEqual(vscCell.outputs, newOutput)) {
110111
return;
111112
}
112113
vscCell.outputs = newOutput;

src/client/datascience/notebook/kernelProvider.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
import * as fastDeepEqual from 'fast-deep-equal';
45
import { inject, injectable } from 'inversify';
56
import { CancellationToken, Event, EventEmitter } from 'vscode';
67
import {
@@ -13,6 +14,7 @@ import { IVSCodeNotebook } from '../../common/application/types';
1314
import { createPromiseFromCancellation } from '../../common/cancellation';
1415
import { IDisposableRegistry } from '../../common/types';
1516
import { noop } from '../../common/utils/misc';
17+
import { KernelProvider } from '../jupyter/kernels/kernelProvider';
1618
import { KernelSelectionProvider } from '../jupyter/kernels/kernelSelections';
1719
import { KernelSelector } from '../jupyter/kernels/kernelSelector';
1820
import { KernelSwitcher } from '../jupyter/kernels/kernelSwitcher';
@@ -22,6 +24,7 @@ import { INotebook, INotebookProvider } from '../types';
2224
import { getNotebookMetadata, isJupyterNotebook, updateKernelInNotebookMetadata } from './helpers/helpers';
2325
import { NotebookKernel } from './notebookKernel';
2426
import { INotebookContentProvider, INotebookExecutionService } from './types';
27+
2528
@injectable()
2629
export class VSCodeKernelPickerProvider implements NotebookKernelProvider {
2730
public get onDidChangeKernels(): Event<void> {
@@ -33,6 +36,7 @@ export class VSCodeKernelPickerProvider implements NotebookKernelProvider {
3336
@inject(INotebookExecutionService) private readonly execution: INotebookExecutionService,
3437
@inject(KernelSelectionProvider) private readonly kernelSelectionProvider: KernelSelectionProvider,
3538
@inject(KernelSelector) private readonly kernelSelector: KernelSelector,
39+
@inject(KernelProvider) private readonly kernelProvider: KernelProvider,
3640
@inject(IVSCodeNotebook) private readonly notebook: IVSCodeNotebook,
3741
@inject(INotebookStorageProvider) private readonly storageProvider: INotebookStorageProvider,
3842
@inject(INotebookProvider) private readonly notebookProvider: INotebookProvider,
@@ -87,14 +91,14 @@ export class VSCodeKernelPickerProvider implements NotebookKernelProvider {
8791
if (
8892
preferredKernel.kernelSpec &&
8993
item.kernelSpec &&
90-
JSON.stringify(preferredKernel.kernelSpec) === JSON.stringify(item.kernelSpec)
94+
fastDeepEqual(preferredKernel.kernelSpec, item.kernelSpec)
9195
) {
9296
return true;
9397
}
9498
if (
9599
preferredKernel.kernelModel &&
96100
item.kernelModel &&
97-
JSON.stringify(preferredKernel.kernelModel) === JSON.stringify(item.kernelModel)
101+
fastDeepEqual(preferredKernel.kernelModel, item.kernelModel)
98102
) {
99103
return true;
100104
}
@@ -130,12 +134,23 @@ export class VSCodeKernelPickerProvider implements NotebookKernelProvider {
130134
// Possibly closed or different kernel picked.
131135
return;
132136
}
137+
133138
const model = await this.storageProvider.getOrCreateModel(document.uri);
134139
if (!model || !model.isTrusted) {
135140
// If a model is not trusted, we cannot change the kernel (this results in changes to notebook metadata).
136141
// This is because we store selected kernel in the notebook metadata.
137142
return;
138143
}
144+
145+
// Check what the existing kernel is.
146+
const existingKernel = this.kernelProvider.get(document.uri);
147+
if (existingKernel && fastDeepEqual(existingKernel.metadata, newKernelInfo.kernel.selection)) {
148+
return;
149+
}
150+
151+
// Make this the new kernel (calling this method will associate the new kernel with this Uri).
152+
this.kernelProvider.getOrCreate(document.uri, { metadata: newKernelInfo.kernel.selection });
153+
139154
// Change kernel and update metadata.
140155
const notebook = await this.notebookProvider.getOrCreateNotebook({
141156
resource: document.uri,

src/client/datascience/notebook/notebookKernel.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class NotebookKernel implements VSCNotebookKernel {
5757
constructor(
5858
public readonly label: string,
5959
public readonly description: string,
60-
private readonly selection: KernelSelection,
60+
public readonly selection: Readonly<KernelSelection>,
6161
public readonly isPreferred: boolean,
6262
private readonly execution: INotebookExecutionService,
6363
private readonly kernelSelectionUsage: IKernelSelectionUsage

0 commit comments

Comments
 (0)