1- import React , { useCallback , useState , useEffect } from 'react' ;
1+ import React , { useRef , useState , useEffect } from 'react' ;
22import { ISignal } from '@lumino/signaling' ;
33import { ReactWidget , ISessionContext } from '@jupyterlab/apputils' ;
44import { IChangedArgs } from '@jupyterlab/coreutils' ;
@@ -113,12 +113,6 @@ const BlankReason = (props: {
113113 { props . trans . __ ( 'No active kernel found.' ) }
114114 </ div >
115115 ) ;
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- ) ;
122116 } else {
123117 return (
124118 < div className = "jp-KernelUsage-section-separator" >
@@ -149,30 +143,35 @@ const KernelUsage = (props: {
149143 }
150144 } , POLL_INTERVAL_SEC * 1000 ) ;
151145
152- const requestUsage = useCallback ( ( kid : string ) => {
146+ const kernelIdRef = useRef < string | undefined > ( kernelId ) ;
147+ kernelIdRef . current = kernelId ;
148+
149+ const requestUsage = ( kid : string ) => {
153150 return requestAPI < any > ( `get_usage/${ kid } ` ) . then ( ( data ) => {
154151 // The kernel reply may arrive late due to lax timeouts, so we need to
155152 // 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
158156 return ;
159157 }
160158
161159 if ( data . content ?. reason ) {
162160 const reason = data . content ;
163161 setReason ( reason ) ;
164162 return ;
163+ } else {
164+ setReason ( undefined ) ;
165165 }
166166
167167 const usage : Usage = {
168168 ...data . content ,
169169 timestamp : new Date ( ) ,
170170 kernel_id : kid ,
171171 } ;
172- setReason ( undefined ) ;
173172 setUsage ( usage ) ;
174173 } ) ;
175- } , [ ] ) ;
174+ } ;
176175
177176 useEffect ( ( ) => {
178177 const createKernelChangeCallback = ( panel : IWidgetWithSession ) => {
@@ -226,6 +225,8 @@ const KernelUsage = (props: {
226225 setKernelId ( kernelId ) ;
227226 const path = panel . sessionContext . session ?. model . path ;
228227 setPath ( path ) ;
228+ setUsage ( undefined ) ;
229+ setReason ( { reason : 'loading' } ) ;
229230 requestUsage ( kernelId ) ;
230231 } else {
231232 setKernelId ( undefined ) ;
@@ -243,7 +244,11 @@ const KernelUsage = (props: {
243244 } ;
244245 } , [ kernelId ] ) ;
245246
246- if ( blankStateReason && ! ( blankStateReason ?. reason === 'timeout' && usage ) ) {
247+ if (
248+ blankStateReason &&
249+ blankStateReason ?. reason !== 'timeout' &&
250+ blankStateReason ?. reason !== 'loading'
251+ ) {
247252 return (
248253 < >
249254 < h3 className = "jp-KernelUsage-section-separator" >
@@ -254,108 +259,112 @@ const KernelUsage = (props: {
254259 ) ;
255260 }
256261 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 >
268315 ) }
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 >
303319 < 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 ) }
310322 </ 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 && (
332323 < 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 ) }
335326 </ 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' ? (
341355 < div className = "jp-KernelUsage-separator" >
342- { props . trans . __ ( 'Used:' ) } { ' ' }
343- { formatForDisplay ( usage . host_virtual_memory . used ) }
356+ { props . trans . __ ( 'Loading…' ) }
344357 </ div >
358+ ) : (
345359 < div className = "jp-KernelUsage-separator" >
346- { props . trans . __ ( 'Wired:' ) } { ' ' }
347- { formatForDisplay ( usage . host_virtual_memory . wired ) }
360+ { props . trans . __ ( 'Usage data is missing' ) }
348361 </ div >
349- </ div >
350- </ >
351- ) ;
352- }
362+ ) }
363+ </ div >
364+ </ >
365+ ) ;
353366 }
354- return (
355- < >
356- < h3 > { props . trans . __ ( 'Kernel usage is missing' ) } </ h3 >
357- </ >
358- ) ;
367+ return < h3 > { props . trans . __ ( 'Kernel usage is missing' ) } </ h3 > ;
359368} ;
360369
361370export class KernelUsageWidget extends ReactWidget {
0 commit comments