mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-22 09:35:37 -05:00
Notebooks: Use new Python installation after configuration change (#14765)
* start new jupyter server * restart session working (removed extra code) * only restart server once * shutdown session first then stop server * add comments remove extra lines * add comment * fix test * only restart jupyter sessions * Dispose jupytersessionmanager and create new one * move restart server logic out of notebookmodel * move methods to azdata proposed * pr comment
This commit is contained in:
@@ -255,6 +255,14 @@ class SessionManagerWrapper implements azdata.nb.SessionManager {
|
||||
this._specs = specs;
|
||||
}
|
||||
}
|
||||
|
||||
shutdownAll(): Thenable<void> {
|
||||
return this._proxy.ext.$shutdownAll(this.managerHandle);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
return this._proxy.ext.$dispose(this.managerHandle);
|
||||
}
|
||||
}
|
||||
|
||||
class SessionWrapper implements azdata.nb.ISession {
|
||||
|
||||
@@ -126,6 +126,12 @@ export class ExtHostNotebook implements ExtHostNotebookShape {
|
||||
});
|
||||
}
|
||||
|
||||
$shutdownAll(managerHandle: number): Thenable<void> {
|
||||
return this._withSessionManager(managerHandle, async (sessionManager) => {
|
||||
return sessionManager.shutdownAll();
|
||||
});
|
||||
}
|
||||
|
||||
$changeKernel(sessionId: number, kernelInfo: azdata.nb.IKernelSpec): Thenable<INotebookKernelDetails> {
|
||||
let session = this._getAdapter<azdata.nb.ISession>(sessionId);
|
||||
return session.changeKernel(kernelInfo).then(kernel => this.saveKernel(kernel));
|
||||
@@ -207,6 +213,12 @@ export class ExtHostNotebook implements ExtHostNotebookShape {
|
||||
future.dispose();
|
||||
}
|
||||
|
||||
$dispose(managerHandle: number): Thenable<void> {
|
||||
return this._withSessionManager(managerHandle, async (sessionManager) => {
|
||||
return sessionManager.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region APIs called by extensions
|
||||
|
||||
@@ -870,6 +870,8 @@ export interface ExtHostNotebookShape {
|
||||
$refreshSpecs(managerHandle: number): Thenable<azdata.nb.IAllKernels>;
|
||||
$startNewSession(managerHandle: number, options: azdata.nb.ISessionOptions): Thenable<INotebookSessionDetails>;
|
||||
$shutdownSession(managerHandle: number, sessionId: string): Thenable<void>;
|
||||
$shutdownAll(managerHandle: number): Thenable<void>;
|
||||
$dispose(managerHandle: number): void;
|
||||
|
||||
// Session APIs
|
||||
$changeKernel(sessionId: number, kernelInfo: azdata.nb.IKernelSpec): Thenable<INotebookKernelDetails>;
|
||||
|
||||
@@ -254,6 +254,10 @@ export abstract class NotebookInput extends EditorInput {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
public get notebookModel(): INotebookModel | undefined {
|
||||
return this._model.getNotebookModel();
|
||||
}
|
||||
|
||||
public get notebookFindModel(): NotebookFindModel {
|
||||
if (!this._notebookFindModel) {
|
||||
this._notebookFindModel = new NotebookFindModel(this._model.getNotebookModel());
|
||||
|
||||
@@ -7,7 +7,7 @@ import { EditorDescriptor, IEditorRegistry, Extensions as EditorExtensions } fro
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IEditorInputFactoryRegistry, Extensions as EditorInputFactoryExtensions, ActiveEditorContext } from 'vs/workbench/common/editor';
|
||||
import { IEditorInputFactoryRegistry, Extensions as EditorInputFactoryExtensions, ActiveEditorContext, IEditorInput } from 'vs/workbench/common/editor';
|
||||
|
||||
import { ILanguageAssociationRegistry, Extensions as LanguageAssociationExtensions } from 'sql/workbench/services/languageAssociation/common/languageAssociation';
|
||||
import { UntitledNotebookInput } from 'sql/workbench/contrib/notebook/browser/models/untitledNotebookInput';
|
||||
@@ -33,7 +33,7 @@ import { MssqlNodeContext } from 'sql/workbench/services/objectExplorer/browser/
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { TreeViewItemHandleArg } from 'sql/workbench/common/views';
|
||||
import { ConnectedContext } from 'azdata';
|
||||
import { ConnectedContext, nb } from 'azdata';
|
||||
import { TreeNodeContextKey } from 'sql/workbench/services/objectExplorer/common/treeNodeContextKey';
|
||||
import { ObjectExplorerActionsContext } from 'sql/workbench/services/objectExplorer/browser/objectExplorerActions';
|
||||
import { ItemContextKey } from 'sql/workbench/contrib/dashboard/browser/widgets/explorer/explorerContext';
|
||||
@@ -52,6 +52,9 @@ import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { SearchSortOrder } from 'vs/workbench/services/search/common/search';
|
||||
import { ImageMimeTypes } from 'sql/workbench/services/notebook/common/contracts';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { NotebookInput } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
||||
import { INotebookModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
||||
import { INotebookManager } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||
|
||||
Registry.as<IEditorInputFactoryRegistry>(EditorInputFactoryExtensions.EditorInputFactories)
|
||||
.registerEditorInputFactory(FileNotebookInput.ID, FileNoteBookEditorInputFactory);
|
||||
@@ -167,6 +170,40 @@ CommandsRegistry.registerCommand({
|
||||
}
|
||||
});
|
||||
|
||||
const RESTART_JUPYTER_NOTEBOOK_SESSIONS = 'notebook.action.restartJupyterNotebookSessions';
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: RESTART_JUPYTER_NOTEBOOK_SESSIONS,
|
||||
handler: async (accessor: ServicesAccessor) => {
|
||||
const editorService: IEditorService = accessor.get(IEditorService);
|
||||
const editors: readonly IEditorInput[] = editorService.editors;
|
||||
let jupyterServerRestarted: boolean = false;
|
||||
|
||||
for (let editor of editors) {
|
||||
if (editor instanceof NotebookInput) {
|
||||
let model: INotebookModel = editor.notebookModel;
|
||||
if (model.providerId === 'jupyter') {
|
||||
// Jupyter server needs to be restarted so that the correct Python installation is used
|
||||
if (!jupyterServerRestarted) {
|
||||
let jupyterNotebookManager: INotebookManager = model.notebookManagers.find(x => x.providerId === 'jupyter');
|
||||
// Shutdown all current Jupyter sessions before stopping the server
|
||||
await jupyterNotebookManager.sessionManager.shutdownAll();
|
||||
// Jupyter session manager needs to be disposed so that a new one is created with the new server info
|
||||
jupyterNotebookManager.sessionManager.dispose();
|
||||
await jupyterNotebookManager.serverManager.stopServer();
|
||||
let spec: nb.IKernelSpec = model.defaultKernel;
|
||||
await jupyterNotebookManager.serverManager.startServer(spec);
|
||||
jupyterServerRestarted = true;
|
||||
}
|
||||
|
||||
// Start a new session for each Jupyter notebook
|
||||
await model.restartSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: TOGGLE_TAB_FOCUS_COMMAND_ID,
|
||||
|
||||
@@ -42,6 +42,13 @@ export class SessionManager implements nb.SessionManager {
|
||||
shutdown(id: string): Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
shutdownAll(): Thenable<void> {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
}
|
||||
}
|
||||
|
||||
export class EmptySession implements nb.ISession {
|
||||
|
||||
@@ -88,6 +88,9 @@ export class NotebookModelStub implements INotebookModel {
|
||||
getStandardKernelFromName(name: string): IStandardKernelWithProvider {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
restartSession(): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
changeKernel(displayName: string): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
@@ -361,6 +361,11 @@ export interface INotebookModel {
|
||||
*/
|
||||
getMetaValue(key: string): any;
|
||||
|
||||
/**
|
||||
* Restart current active session if it exists
|
||||
*/
|
||||
restartSession(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Change the current kernel from the Kernel dropdown
|
||||
* @param displayName kernel name (as displayed in Kernel dropdown)
|
||||
@@ -387,7 +392,6 @@ export interface INotebookModel {
|
||||
*/
|
||||
moveCell(cellModel: ICellModel, direction: MoveDirection): void;
|
||||
|
||||
|
||||
/**
|
||||
* Deletes a cell
|
||||
*/
|
||||
@@ -403,7 +407,6 @@ export interface INotebookModel {
|
||||
*/
|
||||
onCellChange(cell: ICellModel, change: NotebookChangeType): void;
|
||||
|
||||
|
||||
/**
|
||||
* Push edit operations, basically editing the model. This is the preferred way of
|
||||
* editing the model. Long-term, this will ensure edit operations can be added to the undo stack
|
||||
|
||||
@@ -741,6 +741,14 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
||||
}
|
||||
}
|
||||
|
||||
public async restartSession(): Promise<void> {
|
||||
if (this._activeClientSession) {
|
||||
// Old active client sessions have already been shutdown by RESTART_JUPYTER_NOTEBOOK_SESSIONS command
|
||||
this._activeClientSession = undefined;
|
||||
await this.startSession(this.notebookManager, this._selectedKernelDisplayName, true);
|
||||
}
|
||||
}
|
||||
|
||||
// When changing kernel, update the active session
|
||||
private updateActiveClientSession(clientSession: IClientSession) {
|
||||
this._activeClientSession = clientSession;
|
||||
@@ -1114,7 +1122,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
||||
}
|
||||
}
|
||||
|
||||
private async shutdownActiveSession() {
|
||||
private async shutdownActiveSession(): Promise<void> {
|
||||
if (this._activeClientSession) {
|
||||
try {
|
||||
await this._activeClientSession.ready;
|
||||
|
||||
@@ -133,6 +133,16 @@ export class SqlSessionManager implements nb.SessionManager {
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
shutdownAll(): Thenable<void> {
|
||||
return Promise.all(SqlSessionManager._sessions.map(session => {
|
||||
return this.shutdown(session.id);
|
||||
})).then();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
export class SqlSession implements nb.ISession {
|
||||
|
||||
@@ -161,6 +161,9 @@ class ExtHostNotebookStub implements ExtHostNotebookShape {
|
||||
$shutdownSession(managerHandle: number, sessionId: string): Thenable<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
$shutdownAll(managerHandle: number): Thenable<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
$changeKernel(sessionId: number, kernelInfo: azdata.nb.IKernelSpec): Thenable<INotebookKernelDetails> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
@@ -191,4 +194,7 @@ class ExtHostNotebookStub implements ExtHostNotebookShape {
|
||||
$disposeFuture(futureId: number): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
$dispose(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user