44} from '@jupyterlab/application' ;
55import type { CommandRegistry } from '@lumino/commands' ;
66import type { Message } from '@lumino/messaging' ;
7+ import { Signal , ISignal } from '@lumino/signaling' ;
78import {
89 SessionContextDialogs ,
910 ISessionContextDialogs ,
@@ -70,14 +71,24 @@ class CustomSessionContextDialogs extends SessionContextDialogs {
7071 const hasCheckbox = typeof autoStartDefault === 'boolean' ;
7172 const settings = await this . options . settingRegistry . load ( MAIN_PLUGIN_ID ) ;
7273
74+ const dataChanged = new Signal < CustomSessionContextDialogs , void > ( this ) ;
75+ sessionContext . sessionManager . runningChanged . connect ( ( ) => {
76+ dataChanged . emit ( ) ;
77+ } ) ;
78+ this . options . kernelManager . runningChanged . connect ( ( ) => {
79+ dataChanged . emit ( ) ;
80+ } ) ;
81+
7382 const dialog = new Dialog < Partial < Kernel . IModel > | null > ( {
7483 title : trans . __ ( 'Select Kernel' ) ,
7584 body : new KernelSelector ( {
76- data : {
85+ data : ( ) => ( {
7786 specs : sessionContext . specsManager . specs ,
7887 sessions : sessionContext . sessionManager . running ( ) ,
88+ kernels : this . options . kernelManager . running ( ) ,
7989 preference : sessionContext . kernelPreference
80- } ,
90+ } ) ,
91+ dataChanged,
8192 name : sessionContext . name ,
8293 commands : this . options . commands ,
8394 favoritesDatabase : this . options . database . favorites ,
@@ -131,6 +142,7 @@ export namespace CustomSessionContextDialogs {
131142 database : ILauncherDatabase ;
132143 commands : CommandRegistry ;
133144 settingRegistry : ISettingRegistry ;
145+ kernelManager : Kernel . IManager ;
134146 }
135147}
136148
@@ -154,7 +166,8 @@ export const sessionDialogsPlugin: JupyterFrontEndPlugin<ISessionContextDialogs>
154166 translator : translator ,
155167 database : database ,
156168 commands : app . commands ,
157- settingRegistry : settingRegistry
169+ settingRegistry : settingRegistry ,
170+ kernelManager : app . serviceManager . kernels
158171 } ) ;
159172 }
160173 } ;
@@ -190,6 +203,7 @@ export class KernelSelector extends ReactWidget {
190203
191204 onAfterAttach ( msg : Message ) {
192205 super . onAfterAttach ( msg ) ;
206+ this . options . dataChanged . connect ( this . update . bind ( this ) ) ;
193207 requestAnimationFrame ( ( ) => {
194208 // Set minimum dimensions so that when user starts typing to filter
195209 // the kernels the dialog does not start jumping around.
@@ -199,12 +213,18 @@ export class KernelSelector extends ReactWidget {
199213 } ) ;
200214 }
201215
216+ onAfterDetach ( msg : Message ) {
217+ super . onAfterDetach ( msg ) ;
218+ this . options . dataChanged . disconnect ( this . update ) ;
219+ }
220+
202221 /**
203222 * Render the launcher to virtual DOM nodes.
204223 */
205224 protected render ( ) : React . ReactElement < any > | null {
206225 const items : ILauncher . IItemOptions [ ] = [ ] ;
207- const specs = this . options . data . specs ! . kernelspecs ! ;
226+ const data = this . options . data ( ) ;
227+ const specs = data . specs ! . kernelspecs ! ;
208228 // Note: this command is not executed, but it is only used to match favourite/last used metadata
209229 const command =
210230 this . options . type === 'console'
@@ -236,8 +256,14 @@ export class KernelSelector extends ReactWidget {
236256 } ) ;
237257 }
238258 const runningItems : ILauncher . IItemOptions [ ] = [ ] ;
239- for ( const model of this . options . data . sessions ! ) {
240- const kernel = model . kernel ;
259+ const kernels = new Map ( [ ...data . kernels ] . map ( k => [ k . id , k ] ) ) ;
260+ for ( const model of data . sessions ! ) {
261+ // session models may be outdated, use the more frequently
262+ // updated instance from the kernels manager
263+ if ( ! model . kernel ) {
264+ continue ;
265+ }
266+ const kernel = kernels . get ( model . kernel ?. id ) ;
241267 if ( ! kernel ) {
242268 continue ;
243269 }
@@ -344,7 +370,10 @@ export namespace KernelSelector {
344370 settings : ISettingRegistry . ISettings ;
345371 commands : CommandRegistry ;
346372 trans : TranslationBundle ;
347- data : SessionContext . IKernelSearch ;
373+ data : ( ) => SessionContext . IKernelSearch & {
374+ kernels : IterableIterator < Kernel . IModel > ;
375+ } ;
376+ dataChanged : ISignal < CustomSessionContextDialogs , void > ;
348377 acceptDialog : ( ) => void ;
349378 name : string ;
350379 // known values are "notebook" and "console"
0 commit comments