9
9
NotebookCellOutput ,
10
10
NotebookCellExecutionState ,
11
11
Event ,
12
- EventEmitter
12
+ EventEmitter ,
13
+ CancellationToken
13
14
} from 'vscode' ;
14
15
15
16
import { Kernel } from '@jupyterlab/services' ;
@@ -20,7 +21,6 @@ import { disposeAllDisposables } from '../../platform/common/helpers';
20
21
import { traceError , traceInfoIfCI , traceVerbose , traceWarning } from '../../platform/logging' ;
21
22
import { IDisposable } from '../../platform/common/types' ;
22
23
import { createDeferred } from '../../platform/common/utils/async' ;
23
- import { StopWatch } from '../../platform/common/utils/stopWatch' ;
24
24
import { noop } from '../../platform/common/utils/misc' ;
25
25
import { getDisplayNameOrNameOfKernelConnection } from '../../kernels/helpers' ;
26
26
import { isCancellationError } from '../../platform/common/cancellation' ;
@@ -49,7 +49,10 @@ export class CellExecutionFactory {
49
49
code : string | undefined ,
50
50
metadata : Readonly < KernelConnectionMetadata > ,
51
51
resumeExecutionMsgId ?: string ,
52
- restoreOutput ?: boolean
52
+ restoreOutput ?: boolean ,
53
+ token ?: CancellationToken ,
54
+ startTime ?: number ,
55
+ executionCount ?: number
53
56
) {
54
57
// eslint-disable-next-line @typescript-eslint/no-use-before-define
55
58
return CellExecution . fromCell (
@@ -59,7 +62,10 @@ export class CellExecutionFactory {
59
62
this . controller ,
60
63
this . requestListener ,
61
64
resumeExecutionMsgId ,
62
- restoreOutput
65
+ restoreOutput ,
66
+ token ,
67
+ startTime ,
68
+ executionCount
63
69
) ;
64
70
}
65
71
}
@@ -81,8 +87,6 @@ export class CellExecution implements IDisposable {
81
87
return this . _preExecuteEmitter . event ;
82
88
}
83
89
84
- private stopWatch = new StopWatch ( ) ;
85
-
86
90
private readonly _result = createDeferred < NotebookCellRunState > ( ) ;
87
91
88
92
private started ?: boolean ;
@@ -97,14 +101,18 @@ export class CellExecution implements IDisposable {
97
101
private readonly disposables : IDisposable [ ] = [ ] ;
98
102
private _preExecuteEmitter = new EventEmitter < NotebookCell > ( ) ;
99
103
private cellExecutionHandler ?: CellExecutionMessageHandler ;
104
+ private cancelRequested ?: boolean ;
100
105
private constructor (
101
106
public readonly cell : NotebookCell ,
102
107
private readonly codeOverride : string | undefined ,
103
108
private readonly kernelConnection : Readonly < KernelConnectionMetadata > ,
104
109
private readonly controller : IKernelController ,
105
110
private readonly requestListener : CellExecutionMessageHandlerService ,
106
111
private readonly resumeExecutionMsgId ?: string ,
107
- private readonly restoreOutput ?: boolean
112
+ private readonly restoreOutput ?: boolean ,
113
+ private readonly token ?: CancellationToken ,
114
+ private readonly _startTime ?: number ,
115
+ private readonly executionCount ?: number
108
116
) {
109
117
workspace . onDidCloseTextDocument (
110
118
( e ) => {
@@ -152,7 +160,10 @@ export class CellExecution implements IDisposable {
152
160
controller : IKernelController ,
153
161
requestListener : CellExecutionMessageHandlerService ,
154
162
resumeExecutionMsgId ?: string ,
155
- restoreOutput ?: boolean
163
+ restoreOutput ?: boolean ,
164
+ token ?: CancellationToken ,
165
+ startTime ?: number ,
166
+ executionCount ?: number
156
167
) {
157
168
return new CellExecution (
158
169
cell ,
@@ -161,11 +172,14 @@ export class CellExecution implements IDisposable {
161
172
controller ,
162
173
requestListener ,
163
174
resumeExecutionMsgId ,
164
- restoreOutput
175
+ restoreOutput ,
176
+ token ,
177
+ startTime ,
178
+ executionCount
165
179
) ;
166
180
}
167
181
public async resume ( session : IKernelConnectionSession ) {
168
- if ( this . cancelHandled ) {
182
+ if ( this . cancelHandled || this . token ?. isCancellationRequested ) {
169
183
traceCellMessage ( this . cell , 'Not resuming as it was cancelled' ) ;
170
184
return ;
171
185
}
@@ -186,11 +200,13 @@ export class CellExecution implements IDisposable {
186
200
}
187
201
this . started = true ;
188
202
189
- this . startTime = new Date ( ) . getTime ( ) ;
203
+ this . startTime = this . _startTime || new Date ( ) . getTime ( ) ;
190
204
activeNotebookCellExecution . set ( this . cell . notebook , this . execution ) ;
191
205
this . execution ?. start ( this . startTime ) ;
206
+ if ( this . executionCount && this . execution ) {
207
+ this . execution . executionOrder = this . executionCount ;
208
+ }
192
209
NotebookCellStateTracker . setCellState ( this . cell , NotebookCellExecutionState . Executing ) ;
193
- this . stopWatch . reset ( ) ;
194
210
195
211
this . cellExecutionHandler = this . requestListener . registerListenerForResumingExecution ( this . cell , {
196
212
kernel : session . kernel ! ,
@@ -237,7 +253,6 @@ export class CellExecution implements IDisposable {
237
253
// Else when running cells with existing outputs, the outputs don't get cleared & it doesn't look like its running.
238
254
// Ideally we shouldn't have any awaits, but here we want the UI to get updated.
239
255
await this . execution ?. clearOutput ( ) ;
240
- this . stopWatch . reset ( ) ;
241
256
242
257
// Begin the request that will modify our cell.
243
258
this . execute ( this . codeOverride || this . cell . document . getText ( ) . replace ( / \r \n / g, '\n' ) , session )
@@ -258,6 +273,7 @@ export class CellExecution implements IDisposable {
258
273
if ( this . cancelHandled ) {
259
274
return ;
260
275
}
276
+ this . cancelRequested = true ;
261
277
if ( this . started && ! forced ) {
262
278
// At this point the cell execution can only be stopped from kernel & we should not
263
279
// stop handling execution results & the like from the kernel.
@@ -288,7 +304,11 @@ export class CellExecution implements IDisposable {
288
304
disposeAllDisposables ( this . disposables ) ;
289
305
}
290
306
private completedWithErrors ( error : Partial < Error > ) {
291
- traceWarning ( `Cell completed with errors` , error ) ;
307
+ if ( ! this . disposed && ! this . cancelRequested ) {
308
+ traceWarning ( `Cell completed with errors` , error ) ;
309
+ } else {
310
+ traceWarning ( `Cell completed with errors (${ this . disposed ? 'disposed' : 'cancelled' } )` ) ;
311
+ }
292
312
traceCellMessage ( this . cell , 'Completed with errors' ) ;
293
313
294
314
traceCellMessage ( this . cell , 'Update with error state & output' ) ;
@@ -420,6 +440,7 @@ export class CellExecution implements IDisposable {
420
440
this . cellExecutionHandler = this . requestListener . registerListenerForExecution ( this . cell , {
421
441
kernel : session . kernel ! ,
422
442
cellExecution : this . execution ! ,
443
+ startTime : this . startTime ! ,
423
444
request : this . request ,
424
445
onErrorHandlingExecuteRequestIOPubMessage : ( error ) => {
425
446
traceError ( `Cell (index = ${ this . cell . index } ) execution completed with errors (2).` , error ) ;
@@ -442,9 +463,11 @@ export class CellExecution implements IDisposable {
442
463
this . completedSuccessfully ( ) ;
443
464
traceCellMessage ( this . cell , 'Executed successfully in executeCell' ) ;
444
465
} catch ( ex ) {
445
- // @jupyterlab /services throws a `Canceled` error when the kernel is interrupted.
446
- // Or even when the kernel dies when running a cell with the code `os.kill(os.getpid(), 9)`
447
- traceError ( 'Error in waiting for cell to complete' , ex ) ;
466
+ if ( ! this . disposed && ! this . cancelRequested ) {
467
+ // @jupyterlab /services throws a `Canceled` error when the kernel is interrupted.
468
+ // Or even when the kernel dies when running a cell with the code `os.kill(os.getpid(), 9)`
469
+ traceError ( 'Error in waiting for cell to complete' , ex ) ;
470
+ }
448
471
traceCellMessage ( this . cell , 'Some other execution error' ) ;
449
472
if ( ex && ex instanceof Error && isCancellationError ( ex , true ) ) {
450
473
// No point displaying the error stack trace from Jupyter npm package.
0 commit comments