55
66import { KernelMessage } from '@jupyterlab/services' ;
77import { NotebookCell , NotebookCellRunState , NotebookDocument } from 'vscode' ;
8- import { IApplicationShell , ICommandManager } from '../../../common/application/types' ;
8+ import { IApplicationShell , ICommandManager , IVSCodeNotebook } from '../../../common/application/types' ;
99import { IDisposable } from '../../../common/types' ;
1010import { noop } from '../../../common/utils/misc' ;
1111import { IInterpreterService } from '../../../interpreter/contracts' ;
@@ -43,9 +43,16 @@ export class KernelExecution implements IDisposable {
4343 private readonly contentProvider : INotebookContentProvider ,
4444 editorProvider : INotebookEditorProvider ,
4545 readonly kernelSelectionUsage : IKernelSelectionUsage ,
46- readonly appShell : IApplicationShell
46+ readonly appShell : IApplicationShell ,
47+ readonly vscNotebook : IVSCodeNotebook
4748 ) {
48- this . executionFactory = new CellExecutionFactory ( this . contentProvider , errorHandler , editorProvider , appShell ) ;
49+ this . executionFactory = new CellExecutionFactory (
50+ this . contentProvider ,
51+ errorHandler ,
52+ editorProvider ,
53+ appShell ,
54+ vscNotebook
55+ ) ;
4956 }
5057
5158 @captureTelemetry ( Telemetry . ExecuteNativeCell , undefined , true )
@@ -78,11 +85,17 @@ export class KernelExecution implements IDisposable {
7885 if ( this . documentExecutions . has ( document ) ) {
7986 return ;
8087 }
88+ const editor = this . vscNotebook . notebookEditors . find ( ( item ) => item . document === document ) ;
89+ if ( ! editor ) {
90+ return ;
91+ }
8192 const cancelTokenSource = new MultiCancellationTokenSource ( ) ;
8293 this . documentExecutions . set ( document , cancelTokenSource ) ;
8394 const kernel = this . getKernel ( document ) ;
84- document . metadata . runState = vscodeNotebookEnums . NotebookRunState . Running ;
8595
96+ await editor . edit ( ( edit ) =>
97+ edit . replaceMetadata ( { ...document . metadata , runState : vscodeNotebookEnums . NotebookRunState . Running } )
98+ ) ;
8699 const codeCellsToExecute = document . cells
87100 . filter ( ( cell ) => cell . cellKind === vscodeNotebookEnums . CellKind . Code )
88101 . filter ( ( cell ) => cell . document . getText ( ) . trim ( ) . length > 0 )
@@ -98,35 +111,31 @@ export class KernelExecution implements IDisposable {
98111 ) ;
99112
100113 try {
101- let executingAPreviousCellHasFailed = false ;
102- await codeCellsToExecute . reduce (
103- ( previousPromise , cellToExecute ) =>
104- previousPromise . then ( ( previousCellState ) => {
105- // If a previous cell has failed or execution cancelled, the get out.
106- if (
107- executingAPreviousCellHasFailed ||
108- cancelTokenSource . token . isCancellationRequested ||
109- previousCellState === vscodeNotebookEnums . NotebookCellRunState . Error
110- ) {
111- executingAPreviousCellHasFailed = true ;
112- codeCellsToExecute . forEach ( ( cell ) => cell . cancel ( ) ) ; // Cancel pending cells.
113- return ;
114- }
115- const result = this . executeIndividualCell ( kernel , cellToExecute ) ;
116- result . finally ( ( ) => this . cellExecutions . delete ( cellToExecute . cell ) ) . catch ( noop ) ;
117- return result ;
118- } ) ,
119- Promise . resolve < NotebookCellRunState | undefined > ( undefined )
120- ) ;
114+ for ( const cellToExecute of codeCellsToExecute ) {
115+ const result = this . executeIndividualCell ( kernel , cellToExecute ) ;
116+ result . finally ( ( ) => this . cellExecutions . delete ( cellToExecute . cell ) ) . catch ( noop ) ;
117+ const executionResult = await result ;
118+ // If a cell has failed or execution cancelled, the get out.
119+ if (
120+ cancelTokenSource . token . isCancellationRequested ||
121+ executionResult === vscodeNotebookEnums . NotebookCellRunState . Error
122+ ) {
123+ await Promise . all ( codeCellsToExecute . map ( ( cell ) => cell . cancel ( ) ) ) ; // Cancel pending cells.
124+ break ;
125+ }
126+ }
121127 } finally {
128+ await Promise . all ( codeCellsToExecute . map ( ( cell ) => cell . cancel ( ) ) ) ; // Cancel pending cells.
122129 this . documentExecutions . delete ( document ) ;
123- document . metadata . runState = vscodeNotebookEnums . NotebookRunState . Idle ;
130+ await editor . edit ( ( edit ) =>
131+ edit . replaceMetadata ( { ...document . metadata , runState : vscodeNotebookEnums . NotebookRunState . Idle } )
132+ ) ;
124133 }
125134 }
126135
127- public cancelCell ( cell : NotebookCell ) : void {
136+ public async cancelCell ( cell : NotebookCell ) {
128137 if ( this . cellExecutions . get ( cell ) ) {
129- this . cellExecutions . get ( cell ) ! . cancel ( ) ;
138+ await this . cellExecutions . get ( cell ) ! . cancel ( ) ;
130139 }
131140 }
132141
@@ -160,11 +169,14 @@ export class KernelExecution implements IDisposable {
160169 return kernel ;
161170 }
162171
163- private onIoPubMessage ( document : NotebookDocument , msg : KernelMessage . IIOPubMessage ) {
172+ private async onIoPubMessage ( document : NotebookDocument , msg : KernelMessage . IIOPubMessage ) {
164173 // tslint:disable-next-line:no-require-imports
165174 const jupyterLab = require ( '@jupyterlab/services' ) as typeof import ( '@jupyterlab/services' ) ;
166- if ( jupyterLab . KernelMessage . isUpdateDisplayDataMsg ( msg ) && handleUpdateDisplayDataMessage ( msg , document ) ) {
167- this . contentProvider . notifyChangesToDocument ( document ) ;
175+ const editor = this . vscNotebook . notebookEditors . find ( ( e ) => e . document === document ) ;
176+ if ( jupyterLab . KernelMessage . isUpdateDisplayDataMsg ( msg ) && editor ) {
177+ if ( await handleUpdateDisplayDataMessage ( msg , editor ) ) {
178+ this . contentProvider . notifyChangesToDocument ( document ) ;
179+ }
168180 }
169181 }
170182
@@ -195,7 +207,7 @@ export class KernelExecution implements IDisposable {
195207 ) ;
196208
197209 // Start execution
198- cellExecution . start ( kernelPromise , this . notebook ) ;
210+ await cellExecution . start ( kernelPromise , this . notebook ) ;
199211
200212 // The result promise will resolve when complete.
201213 try {
0 commit comments