diff --git a/news/2 Fixes/12330.md b/news/2 Fixes/12330.md new file mode 100644 index 000000000000..be52dcbb1c7a --- /dev/null +++ b/news/2 Fixes/12330.md @@ -0,0 +1 @@ +Fix raw kernel autostart and remove jupyter execution from interactive base. \ No newline at end of file diff --git a/src/client/datascience/interactive-common/interactiveBase.ts b/src/client/datascience/interactive-common/interactiveBase.ts index 6e1b2323f29e..6f81dddaccc5 100644 --- a/src/client/datascience/interactive-common/interactiveBase.ts +++ b/src/client/datascience/interactive-common/interactiveBase.ts @@ -80,7 +80,6 @@ import { IInteractiveWindowInfo, IInteractiveWindowListener, IJupyterDebugger, - IJupyterExecution, IJupyterKernelSpec, IJupyterVariableDataProviderFactory, IJupyterVariables, @@ -134,7 +133,6 @@ export abstract class InteractiveBase extends WebViewHost this.activating()); this.disposables.push(handler); - // If our execution changes its liveshare session, we need to close our server - this.jupyterExecution.sessionChanged(() => this.reloadAfterShutdown()); - // For each listener sign up for their post events this.listeners.forEach((l) => l.postMessage((e) => this.postMessageInternal(e.message, e.payload))); // Channel for listeners to send messages to the interactive base. @@ -199,8 +194,8 @@ export abstract class InteractiveBase extends WebViewHost { - // Finish either of our notebook promises - if (this.connectionAndNotebookPromise) { - await this.connectionAndNotebookPromise; - this.connectionAndNotebookPromise = undefined; - } - if (this.notebookPromise) { - await this.notebookPromise; - this.notebookPromise = undefined; - } - // If we have a notebook dispose of it - if (this._notebook) { - const notebook = this._notebook; - this._notebook = undefined; - await notebook.dispose(); - } - - // Disconnect from our notebook provider - await this.notebookProvider.disconnect({ getOnly: true }); - } - // ensureNotebook can be called apart from ensureNotebookAndServer and it needs // the same protection to not be called twice // tslint:disable-next-line: member-ordering @@ -1205,20 +1179,6 @@ export abstract class InteractiveBase extends WebViewHost { - try { - await this.stopServer(); - } catch { - // We just switched from host to guest mode. Don't really care - // if closing the host server kills it. - this._notebook = undefined; - } finally { - this.connectionAndNotebookPromise = undefined; - this.notebookPromise = undefined; - } - await this.ensureConnectionAndNotebook(); - } - @captureTelemetry(Telemetry.GotoSourceCode, undefined, false) private gotoCode(args: IGotoCode) { this.gotoCodeInternal(args.file, args.line).catch((err) => { diff --git a/src/client/datascience/interactive-common/notebookProvider.ts b/src/client/datascience/interactive-common/notebookProvider.ts index 83755403f969..d53ac7b145e8 100644 --- a/src/client/datascience/interactive-common/notebookProvider.ts +++ b/src/client/datascience/interactive-common/notebookProvider.ts @@ -28,6 +28,7 @@ import { export class NotebookProvider implements INotebookProvider { private readonly notebooks = new Map>(); private _notebookCreated = new EventEmitter<{ identity: Uri; notebook: INotebook }>(); + private _connectionMade = new EventEmitter(); private _type: 'jupyter' | 'raw' = 'jupyter'; public get activeNotebooks() { return [...this.notebooks.values()]; @@ -56,6 +57,10 @@ export class NotebookProvider implements INotebookProvider { return this._notebookCreated.event; } + public get onConnectionMade() { + return this._connectionMade.event; + } + public get type(): 'jupyter' | 'raw' { return this._type; } @@ -72,9 +77,15 @@ export class NotebookProvider implements INotebookProvider { public async connect(options: ConnectNotebookProviderOptions): Promise { // Connect to either a jupyter server or a stubbed out raw notebook "connection" if (await this.rawNotebookProvider.supported()) { - return this.rawNotebookProvider.connect(options); + return this.rawNotebookProvider.connect({ + ...options, + onConnectionMade: this.fireConnectionMade.bind(this) + }); } else { - return this.jupyterNotebookProvider.connect(options); + return this.jupyterNotebookProvider.connect({ + ...options, + onConnectionMade: this.fireConnectionMade.bind(this) + }); } } @@ -134,6 +145,10 @@ export class NotebookProvider implements INotebookProvider { return promise; } + private fireConnectionMade() { + this._connectionMade.fire(); + } + // Cache the promise that will return a notebook private cacheNotebookPromise(identity: Uri, promise: Promise) { this.notebooks.set(identity.fsPath, promise); diff --git a/src/client/datascience/interactive-common/notebookServerProvider.ts b/src/client/datascience/interactive-common/notebookServerProvider.ts index 0d697ff6dd1d..c2f50a9ae286 100644 --- a/src/client/datascience/interactive-common/notebookServerProvider.ts +++ b/src/client/datascience/interactive-common/notebookServerProvider.ts @@ -53,7 +53,14 @@ export class NotebookServerProvider implements IJupyterServerProvider { return this.jupyterExecution.getServer(serverOptions); } else { // Otherwise create a new server - return this.createServer(options, token); + return this.createServer(options, token).then((val) => { + // If we created a new server notify of our first time provider connection + if (val && options.onConnectionMade) { + options.onConnectionMade(); + } + + return val; + }); } } diff --git a/src/client/datascience/interactive-ipynb/nativeEditor.ts b/src/client/datascience/interactive-ipynb/nativeEditor.ts index b436b2307ed2..dd3d3aa023fe 100644 --- a/src/client/datascience/interactive-ipynb/nativeEditor.ts +++ b/src/client/datascience/interactive-ipynb/nativeEditor.ts @@ -66,7 +66,6 @@ import { IInteractiveWindowInfo, IInteractiveWindowListener, IJupyterDebugger, - IJupyterExecution, IJupyterKernelSpec, IJupyterVariableDataProviderFactory, IJupyterVariables, @@ -160,7 +159,6 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor { @inject(ICodeCssGenerator) cssGenerator: ICodeCssGenerator, @inject(IThemeFinder) themeFinder: IThemeFinder, @inject(IStatusProvider) statusProvider: IStatusProvider, - @inject(IJupyterExecution) jupyterExecution: IJupyterExecution, @inject(IFileSystem) fileSystem: IFileSystem, @inject(IConfigurationService) configuration: IConfigurationService, @inject(ICommandManager) commandManager: ICommandManager, @@ -193,7 +191,6 @@ export class NativeEditor extends InteractiveBase implements INotebookEditor { cssGenerator, themeFinder, statusProvider, - jupyterExecution, fileSystem, configuration, jupyterExporter, diff --git a/src/client/datascience/interactive-ipynb/nativeEditorOldWebView.ts b/src/client/datascience/interactive-ipynb/nativeEditorOldWebView.ts index 58def5a92b0a..5db34dad06d2 100644 --- a/src/client/datascience/interactive-ipynb/nativeEditorOldWebView.ts +++ b/src/client/datascience/interactive-ipynb/nativeEditorOldWebView.ts @@ -39,7 +39,6 @@ import { IDataScienceErrorHandler, IInteractiveWindowListener, IJupyterDebugger, - IJupyterExecution, IJupyterVariableDataProviderFactory, IJupyterVariables, INotebookEditorProvider, @@ -81,7 +80,6 @@ export class NativeEditorOldWebView extends NativeEditor { @inject(ICodeCssGenerator) cssGenerator: ICodeCssGenerator, @inject(IThemeFinder) themeFinder: IThemeFinder, @inject(IStatusProvider) statusProvider: IStatusProvider, - @inject(IJupyterExecution) jupyterExecution: IJupyterExecution, @inject(IFileSystem) fileSystem: IFileSystem, @inject(IConfigurationService) configuration: IConfigurationService, @inject(ICommandManager) commandManager: ICommandManager, @@ -115,7 +113,6 @@ export class NativeEditorOldWebView extends NativeEditor { cssGenerator, themeFinder, statusProvider, - jupyterExecution, fileSystem, configuration, commandManager, diff --git a/src/client/datascience/interactive-window/interactiveWindow.ts b/src/client/datascience/interactive-window/interactiveWindow.ts index 005e38138021..4a9d70308f68 100644 --- a/src/client/datascience/interactive-window/interactiveWindow.ts +++ b/src/client/datascience/interactive-window/interactiveWindow.ts @@ -52,7 +52,6 @@ import { IInteractiveWindowListener, IInteractiveWindowProvider, IJupyterDebugger, - IJupyterExecution, IJupyterKernelSpec, IJupyterVariableDataProviderFactory, IJupyterVariables, @@ -96,7 +95,6 @@ export class InteractiveWindow extends InteractiveBase implements IInteractiveWi @inject(IDisposableRegistry) disposables: IDisposableRegistry, @inject(ICodeCssGenerator) cssGenerator: ICodeCssGenerator, @inject(IThemeFinder) themeFinder: IThemeFinder, - @inject(IJupyterExecution) jupyterExecution: IJupyterExecution, @inject(IFileSystem) fileSystem: IFileSystem, @inject(IConfigurationService) configuration: IConfigurationService, @inject(ICommandManager) commandManager: ICommandManager, @@ -127,7 +125,6 @@ export class InteractiveWindow extends InteractiveBase implements IInteractiveWi cssGenerator, themeFinder, statusProvider, - jupyterExecution, fileSystem, configuration, jupyterExporter, diff --git a/src/client/datascience/jupyter/jupyterExecution.ts b/src/client/datascience/jupyter/jupyterExecution.ts index 2e4914a13e12..65fcf9b9f04d 100644 --- a/src/client/datascience/jupyter/jupyterExecution.ts +++ b/src/client/datascience/jupyter/jupyterExecution.ts @@ -37,7 +37,6 @@ const LocalHosts = ['localhost', '127.0.0.1', '::1']; export class JupyterExecutionBase implements IJupyterExecution { private usablePythonInterpreter: PythonInterpreter | undefined; - private eventEmitter: EventEmitter = new EventEmitter(); private startedEmitter: EventEmitter = new EventEmitter(); private disposed: boolean = false; private readonly jupyterInterpreterService: IJupyterSubCommandExecutionService; @@ -71,10 +70,6 @@ export class JupyterExecutionBase implements IJupyterExecution { } } - public get sessionChanged(): Event { - return this.eventEmitter.event; - } - public get serverStarted(): Event { return this.startedEmitter.event; } diff --git a/src/client/datascience/raw-kernel/rawNotebookProvider.ts b/src/client/datascience/raw-kernel/rawNotebookProvider.ts index 8d4e39e34b93..dffef32cdbea 100644 --- a/src/client/datascience/raw-kernel/rawNotebookProvider.ts +++ b/src/client/datascience/raw-kernel/rawNotebookProvider.ts @@ -63,6 +63,11 @@ export class RawNotebookProviderBase implements IRawNotebookProvider { // If not get only, create if needed and return if (!this.rawConnection) { this.rawConnection = new RawConnection(); + + // Fire our optional event that we have created a connection + if (options.onConnectionMade) { + options.onConnectionMade(); + } } return Promise.resolve(this.rawConnection); } diff --git a/src/client/datascience/types.ts b/src/client/datascience/types.ts index b3b3cba94fbd..f64d06f7ee2a 100644 --- a/src/client/datascience/types.ts +++ b/src/client/datascience/types.ts @@ -243,6 +243,7 @@ export type ConnectNotebookProviderOptions = { disableUI?: boolean; localOnly?: boolean; token?: CancellationToken; + onConnectionMade?(): void; // Optional callback for when the first connection is made }; export interface INotebookServerOptions { @@ -280,7 +281,6 @@ export interface IGatherLogger extends INotebookExecutionLogger { export const IJupyterExecution = Symbol('IJupyterExecution'); export interface IJupyterExecution extends IAsyncDisposable { - sessionChanged: Event; serverStarted: Event; isNotebookSupported(cancelToken?: CancellationToken): Promise; isImportSupported(cancelToken?: CancellationToken): Promise; @@ -1052,6 +1052,7 @@ export type GetServerOptions = { disableUI?: boolean; localOnly?: boolean; token?: CancellationToken; + onConnectionMade?(): void; // Optional callback for when the first connection is made }; /** @@ -1073,6 +1074,11 @@ export interface INotebookProvider { */ onNotebookCreated: Event<{ identity: Uri; notebook: INotebook }>; + /** + * Fired just the first time that this provider connects + */ + onConnectionMade: Event; + /** * List of all notebooks (active and ones that are being constructed). */ diff --git a/src/test/datascience/interactive-ipynb/nativeEditorProvider.functional.test.ts b/src/test/datascience/interactive-ipynb/nativeEditorProvider.functional.test.ts index dda03edf2c3c..4d2688a8b153 100644 --- a/src/test/datascience/interactive-ipynb/nativeEditorProvider.functional.test.ts +++ b/src/test/datascience/interactive-ipynb/nativeEditorProvider.functional.test.ts @@ -118,9 +118,6 @@ suite('DataScience - Native Editor Provider', () => { const editorChangeEvent = new EventEmitter(); when(docManager.onDidChangeActiveTextEditor).thenReturn(editorChangeEvent.event); - const sessionChangedEvent = new EventEmitter(); - when(executionProvider.sessionChanged).thenReturn(sessionChangedEvent.event); - const serverStartedEvent = new EventEmitter(); when(executionProvider.serverStarted).thenReturn(serverStartedEvent.event); diff --git a/src/test/datascience/interactive-ipynb/nativeEditorStorage.unit.test.ts b/src/test/datascience/interactive-ipynb/nativeEditorStorage.unit.test.ts index 5c672f1b42d7..7dd3bf696432 100644 --- a/src/test/datascience/interactive-ipynb/nativeEditorStorage.unit.test.ts +++ b/src/test/datascience/interactive-ipynb/nativeEditorStorage.unit.test.ts @@ -269,9 +269,6 @@ suite('DataScience - Native Editor Storage', () => { const editorChangeEvent = new EventEmitter(); when(docManager.onDidChangeActiveTextEditor).thenReturn(editorChangeEvent.event); - const sessionChangedEvent = new EventEmitter(); - when(executionProvider.sessionChanged).thenReturn(sessionChangedEvent.event); - const serverStartedEvent = new EventEmitter(); when(executionProvider.serverStarted).thenReturn(serverStartedEvent.event); diff --git a/src/test/datascience/uiTests/ipywidget.ui.functional.test.ts b/src/test/datascience/uiTests/ipywidget.ui.functional.test.ts index cb3c417d9ae4..7747db5b3fdf 100644 --- a/src/test/datascience/uiTests/ipywidget.ui.functional.test.ts +++ b/src/test/datascience/uiTests/ipywidget.ui.functional.test.ts @@ -201,7 +201,7 @@ use(chaiAsPromised); assert.include(outputHtml, '