1
- import React , { useCallback , useState , useEffect } from 'react' ;
1
+ import React , { useRef , useState , useEffect } from 'react' ;
2
2
import { ISignal } from '@lumino/signaling' ;
3
3
import { ReactWidget , ISessionContext } from '@jupyterlab/apputils' ;
4
4
import { IChangedArgs } from '@jupyterlab/coreutils' ;
@@ -113,12 +113,6 @@ const BlankReason = (props: {
113
113
{ props . trans . __ ( 'No active kernel found.' ) }
114
114
</ div >
115
115
) ;
116
- } else if ( reason . reason === 'loading' ) {
117
- return (
118
- < div className = "jp-KernelUsage-section-separator" >
119
- { props . trans . __ ( 'Kernel usage is loading.' ) }
120
- </ div >
121
- ) ;
122
116
} else {
123
117
return (
124
118
< div className = "jp-KernelUsage-section-separator" >
@@ -149,30 +143,35 @@ const KernelUsage = (props: {
149
143
}
150
144
} , POLL_INTERVAL_SEC * 1000 ) ;
151
145
152
- const requestUsage = useCallback ( ( kid : string ) => {
146
+ const kernelIdRef = useRef < string | undefined > ( kernelId ) ;
147
+ kernelIdRef . current = kernelId ;
148
+
149
+ const requestUsage = ( kid : string ) => {
153
150
return requestAPI < any > ( `get_usage/${ kid } ` ) . then ( ( data ) => {
154
151
// The kernel reply may arrive late due to lax timeouts, so we need to
155
152
// check if it is for the current kernel
156
- if ( data . kernel_id && data . kernel_id !== kid ) {
157
- // Ignore outdated response.
153
+
154
+ if ( kid !== kernelIdRef . current ) {
155
+ // Ignore outdated response, but preserve current reason
158
156
return ;
159
157
}
160
158
161
159
if ( data . content ?. reason ) {
162
160
const reason = data . content ;
163
161
setReason ( reason ) ;
164
162
return ;
163
+ } else {
164
+ setReason ( undefined ) ;
165
165
}
166
166
167
167
const usage : Usage = {
168
168
...data . content ,
169
169
timestamp : new Date ( ) ,
170
170
kernel_id : kid ,
171
171
} ;
172
- setReason ( undefined ) ;
173
172
setUsage ( usage ) ;
174
173
} ) ;
175
- } , [ ] ) ;
174
+ } ;
176
175
177
176
useEffect ( ( ) => {
178
177
const createKernelChangeCallback = ( panel : IWidgetWithSession ) => {
@@ -226,6 +225,8 @@ const KernelUsage = (props: {
226
225
setKernelId ( kernelId ) ;
227
226
const path = panel . sessionContext . session ?. model . path ;
228
227
setPath ( path ) ;
228
+ setUsage ( undefined ) ;
229
+ setReason ( { reason : 'loading' } ) ;
229
230
requestUsage ( kernelId ) ;
230
231
} else {
231
232
setKernelId ( undefined ) ;
@@ -243,7 +244,11 @@ const KernelUsage = (props: {
243
244
} ;
244
245
} , [ kernelId ] ) ;
245
246
246
- if ( blankStateReason && ! ( blankStateReason ?. reason === 'timeout' && usage ) ) {
247
+ if (
248
+ blankStateReason &&
249
+ blankStateReason ?. reason !== 'timeout' &&
250
+ blankStateReason ?. reason !== 'loading'
251
+ ) {
247
252
return (
248
253
< >
249
254
< h3 className = "jp-KernelUsage-section-separator" >
@@ -254,108 +259,112 @@ const KernelUsage = (props: {
254
259
) ;
255
260
}
256
261
if ( kernelId ) {
257
- if ( usage ) {
258
- return (
259
- < >
260
- < h3 className = "jp-KernelUsage-section-separator" >
261
- { props . trans . __ ( 'Kernel usage' ) }
262
- </ h3 >
263
- { blankStateReason ?. reason === 'timeout' ? (
264
- < strong >
265
- { props . trans . __ (
266
- 'Timed out in: %1 ms' ,
267
- blankStateReason . timeout_ms
262
+ return (
263
+ < >
264
+ < h3 className = "jp-KernelUsage-section-separator" >
265
+ { props . trans . __ ( 'Kernel usage' ) }
266
+ </ h3 >
267
+ { blankStateReason ?. reason === 'timeout' ? (
268
+ < strong >
269
+ { props . trans . __ ( 'Timed out in: %1 ms' , blankStateReason . timeout_ms ) }
270
+ </ strong >
271
+ ) : null }
272
+ < div className = "jp-KernelUsage-separator" >
273
+ { props . trans . __ ( 'Notebook:' ) } { path }
274
+ </ div >
275
+ < div className = "jp-KernelUsage-separator" >
276
+ { props . trans . __ ( 'Kernel ID:' ) } { kernelId }
277
+ </ div >
278
+ < div
279
+ className = {
280
+ blankStateReason ?. reason === 'timeout' ? TIMEOUT_CLASS : ''
281
+ }
282
+ >
283
+ { usage ? (
284
+ < >
285
+ < div className = "jp-KernelUsage-separator" >
286
+ { props . trans . __ ( 'Kernel Host:' ) } { usage . hostname }
287
+ </ div >
288
+ < div className = "jp-KernelUsage-separator" >
289
+ { props . trans . __ ( 'Timestamp:' ) } { ' ' }
290
+ { usage . timestamp ?. toLocaleString ( ) }
291
+ </ div >
292
+ < div className = "jp-KernelUsage-separator" >
293
+ { props . trans . __ ( 'Process ID:' ) } { usage . pid }
294
+ </ div >
295
+ < div className = "jp-KernelUsage-separator" >
296
+ { props . trans . __ ( 'CPU:' ) } { usage . kernel_cpu }
297
+ </ div >
298
+ < div className = "jp-KernelUsage-separator" >
299
+ { props . trans . __ ( 'Memory:' ) } { ' ' }
300
+ { formatForDisplay ( usage . kernel_memory ) }
301
+ </ div >
302
+ < hr className = "jp-KernelUsage-section-separator" > </ hr >
303
+ < h4 className = "jp-KernelUsage-section-separator" >
304
+ { props . trans . __ ( 'Host CPU' ) }
305
+ </ h4 >
306
+ { usage . host_cpu_percent && (
307
+ < div className = "jp-KernelUsage-separator" >
308
+ { props . trans . _n (
309
+ '%2%% used on %1 CPU' ,
310
+ '%2%% used on %1 CPUs' ,
311
+ usage . cpu_count ,
312
+ usage . host_cpu_percent . toFixed ( 1 )
313
+ ) }
314
+ </ div >
268
315
) }
269
- </ strong >
270
- ) : null }
271
- < div
272
- className = {
273
- blankStateReason ?. reason === 'timeout' ? TIMEOUT_CLASS : ''
274
- }
275
- >
276
- < div className = "jp-KernelUsage-separator" >
277
- { props . trans . __ ( 'Kernel Host:' ) } { usage . hostname }
278
- </ div >
279
- < div className = "jp-KernelUsage-separator" >
280
- { props . trans . __ ( 'Notebook:' ) } { path }
281
- </ div >
282
- < div className = "jp-KernelUsage-separator" >
283
- { props . trans . __ ( 'Kernel ID:' ) } { kernelId }
284
- </ div >
285
- < div className = "jp-KernelUsage-separator" >
286
- { props . trans . __ ( 'Timestamp:' ) } { usage . timestamp ?. toLocaleString ( ) }
287
- </ div >
288
- < div className = "jp-KernelUsage-separator" >
289
- { props . trans . __ ( 'Process ID:' ) } { usage . pid }
290
- </ div >
291
- < div className = "jp-KernelUsage-separator" >
292
- { props . trans . __ ( 'CPU:' ) } { usage . kernel_cpu }
293
- </ div >
294
- < div className = "jp-KernelUsage-separator" >
295
- { props . trans . __ ( 'Memory:' ) } { ' ' }
296
- { formatForDisplay ( usage . kernel_memory ) }
297
- </ div >
298
- < hr className = "jp-KernelUsage-section-separator" > </ hr >
299
- < h4 className = "jp-KernelUsage-section-separator" >
300
- { props . trans . __ ( 'Host CPU' ) }
301
- </ h4 >
302
- { usage . host_cpu_percent && (
316
+ < h4 className = "jp-KernelUsage-section-separator" >
317
+ { props . trans . __ ( 'Host Virtual Memory' ) }
318
+ </ h4 >
303
319
< div className = "jp-KernelUsage-separator" >
304
- { props . trans . _n (
305
- '%2%% used on %1 CPU' ,
306
- '%2%% used on %1 CPUs' ,
307
- usage . cpu_count ,
308
- usage . host_cpu_percent . toFixed ( 1 )
309
- ) }
320
+ { props . trans . __ ( 'Active:' ) } { ' ' }
321
+ { formatForDisplay ( usage . host_virtual_memory . active ) }
310
322
</ div >
311
- ) }
312
- < h4 className = "jp-KernelUsage-section-separator" >
313
- { props . trans . __ ( 'Host Virtual Memory' ) }
314
- </ h4 >
315
- < div className = "jp-KernelUsage-separator" >
316
- { props . trans . __ ( 'Active:' ) } { ' ' }
317
- { formatForDisplay ( usage . host_virtual_memory . active ) }
318
- </ div >
319
- < div className = "jp-KernelUsage-separator" >
320
- { props . trans . __ ( 'Available:' ) } { ' ' }
321
- { formatForDisplay ( usage . host_virtual_memory . available ) }
322
- </ div >
323
- < div className = "jp-KernelUsage-separator" >
324
- { props . trans . __ ( 'Free:' ) } { ' ' }
325
- { formatForDisplay ( usage . host_virtual_memory . free ) }
326
- </ div >
327
- < div className = "jp-KernelUsage-separator" >
328
- { props . trans . __ ( 'Inactive:' ) } { ' ' }
329
- { formatForDisplay ( usage . host_virtual_memory . inactive ) }
330
- </ div >
331
- { usage . host_virtual_memory . percent && (
332
323
< div className = "jp-KernelUsage-separator" >
333
- { props . trans . __ ( 'Percent used :' ) } { ' ' }
334
- { usage . host_virtual_memory . percent . toFixed ( 1 ) } %
324
+ { props . trans . __ ( 'Available :' ) } { ' ' }
325
+ { formatForDisplay ( usage . host_virtual_memory . available ) }
335
326
</ div >
336
- ) }
337
- < div className = "jp-KernelUsage-separator" >
338
- { props . trans . __ ( 'Total:' ) } { ' ' }
339
- { formatForDisplay ( usage . host_virtual_memory . total ) }
340
- </ div >
327
+ < div className = "jp-KernelUsage-separator" >
328
+ { props . trans . __ ( 'Free:' ) } { ' ' }
329
+ { formatForDisplay ( usage . host_virtual_memory . free ) }
330
+ </ div >
331
+ < div className = "jp-KernelUsage-separator" >
332
+ { props . trans . __ ( 'Inactive:' ) } { ' ' }
333
+ { formatForDisplay ( usage . host_virtual_memory . inactive ) }
334
+ </ div >
335
+ { usage . host_virtual_memory . percent && (
336
+ < div className = "jp-KernelUsage-separator" >
337
+ { props . trans . __ ( 'Percent used:' ) } { ' ' }
338
+ { usage . host_virtual_memory . percent . toFixed ( 1 ) } %
339
+ </ div >
340
+ ) }
341
+ < div className = "jp-KernelUsage-separator" >
342
+ { props . trans . __ ( 'Total:' ) } { ' ' }
343
+ { formatForDisplay ( usage . host_virtual_memory . total ) }
344
+ </ div >
345
+ < div className = "jp-KernelUsage-separator" >
346
+ { props . trans . __ ( 'Used:' ) } { ' ' }
347
+ { formatForDisplay ( usage . host_virtual_memory . used ) }
348
+ </ div >
349
+ < div className = "jp-KernelUsage-separator" >
350
+ { props . trans . __ ( 'Wired:' ) } { ' ' }
351
+ { formatForDisplay ( usage . host_virtual_memory . wired ) }
352
+ </ div >
353
+ </ >
354
+ ) : blankStateReason ?. reason === 'loading' ? (
341
355
< div className = "jp-KernelUsage-separator" >
342
- { props . trans . __ ( 'Used:' ) } { ' ' }
343
- { formatForDisplay ( usage . host_virtual_memory . used ) }
356
+ { props . trans . __ ( 'Loading…' ) }
344
357
</ div >
358
+ ) : (
345
359
< div className = "jp-KernelUsage-separator" >
346
- { props . trans . __ ( 'Wired:' ) } { ' ' }
347
- { formatForDisplay ( usage . host_virtual_memory . wired ) }
360
+ { props . trans . __ ( 'Usage data is missing' ) }
348
361
</ div >
349
- </ div >
350
- </ >
351
- ) ;
352
- }
362
+ ) }
363
+ </ div >
364
+ </ >
365
+ ) ;
353
366
}
354
- return (
355
- < >
356
- < h3 > { props . trans . __ ( 'Kernel usage is missing' ) } </ h3 >
357
- </ >
358
- ) ;
367
+ return < h3 > { props . trans . __ ( 'Kernel usage is missing' ) } </ h3 > ;
359
368
} ;
360
369
361
370
export class KernelUsageWidget extends ReactWidget {
0 commit comments