diff --git a/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts b/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts index 86394fdf58d..efc7566861f 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebookKernels.ts @@ -249,4 +249,8 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape } }); } + + $removeExecution(handle: number): void { + this._executions.delete(handle); + } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 8b93af59d2b..c4cac515b3c 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -926,7 +926,15 @@ export interface ICellExecuteOutputItemEditDto { items: NotebookOutputItemDto[] } -export type ICellExecuteUpdateDto = ICellExecuteOutputEditDto | ICellExecuteOutputItemEditDto | ICellExecutionStateUpdate | ICellExecutionComplete; +export interface ICellExecutionStateUpdateDto extends ICellExecutionStateUpdate { + executionHandle: number; +} + +export interface ICellExecutionCompleteDto extends ICellExecutionComplete { + executionHandle: number; +} + +export type ICellExecuteUpdateDto = ICellExecuteOutputEditDto | ICellExecuteOutputItemEditDto | ICellExecutionStateUpdateDto | ICellExecutionCompleteDto; export interface MainThreadNotebookKernelsShape extends IDisposable { $postMessage(handle: number, editorId: string | undefined, message: any): Promise; @@ -937,6 +945,7 @@ export interface MainThreadNotebookKernelsShape extends IDisposable { $addExecution(handle: number, uri: UriComponents, cellHandle: number): void; $updateExecutions(data: ICellExecuteUpdateDto[]): void; + $removeExecution(handle: number): void; } export interface MainThreadNotebookRenderersShape extends IDisposable { diff --git a/src/vs/workbench/api/common/extHostNotebookKernels.ts b/src/vs/workbench/api/common/extHostNotebookKernels.ts index 87e0868cc70..c8b57133dba 100644 --- a/src/vs/workbench/api/common/extHostNotebookKernels.ts +++ b/src/vs/workbench/api/common/extHostNotebookKernels.ts @@ -472,6 +472,8 @@ class NotebookCellExecutionTask extends Disposable { // The last update needs to be ordered correctly and applied immediately, // so we use updateSoon and immediately flush. that._collector.flush(); + + that._proxy.$removeExecution(that._handle); }, clearOutput(cell?: vscode.NotebookCell): Thenable { diff --git a/src/vs/workbench/contrib/notebook/browser/notebookExecutionServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/notebookExecutionServiceImpl.ts index 8213e7c9826..643eb717044 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookExecutionServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookExecutionServiceImpl.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel'; import { CellEditType, ICellEditOperation, NotebookCellExecutionState, NotebookCellInternalMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon'; @@ -67,9 +68,11 @@ function updateToEdit(update: ICellExecuteUpdate, cellHandle: number): ICellEdit throw new Error('Unknown cell update type'); } -class CellExecution implements INotebookCellExecution { +class CellExecution implements INotebookCellExecution, IDisposable { private readonly _notebookModel: NotebookTextModel; + private _isDisposed = false; + constructor( readonly notebook: URI, readonly cellHandle: number, @@ -93,8 +96,20 @@ class CellExecution implements INotebookCellExecution { } update(updates: ICellExecuteUpdate[]): void { + if (this._isDisposed) { + throw new Error('Cannot update disposed execution'); + } + const edits = updates.map(update => updateToEdit(update, this.cellHandle)); this._applyExecutionEdits(edits); + + if (updates.some(u => u.editType === CellExecutionUpdateType.Complete)) { + this.dispose(); + } + } + + dispose(): void { + this._isDisposed = true; } private _applyExecutionEdits(edits: ICellEditOperation[]): void { diff --git a/src/vs/workbench/contrib/notebook/common/notebookExecutionService.ts b/src/vs/workbench/contrib/notebook/common/notebookExecutionService.ts index 7ba8fd9b77a..0f14b023a82 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookExecutionService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookExecutionService.ts @@ -16,7 +16,6 @@ export enum CellExecutionUpdateType { export interface ICellExecuteOutputEdit { editType: CellExecutionUpdateType.Output; - executionHandle: number; cellHandle: number; append?: boolean; outputs: IOutputDto[] @@ -24,7 +23,6 @@ export interface ICellExecuteOutputEdit { export interface ICellExecuteOutputItemEdit { editType: CellExecutionUpdateType.OutputItems; - executionHandle: number; append?: boolean; outputId: string; items: IOutputItemDto[] @@ -34,14 +32,12 @@ export type ICellExecuteUpdate = ICellExecuteOutputEdit | ICellExecuteOutputItem export interface ICellExecutionStateUpdate { editType: CellExecutionUpdateType.ExecutionState; - executionHandle: number; executionOrder?: number; runStartTime?: number; } export interface ICellExecutionComplete { editType: CellExecutionUpdateType.Complete; - executionHandle: number; runEndTime?: number; lastRunSuccess?: boolean; } @@ -57,6 +53,5 @@ export const INotebookExecutionService = createDecorator