@@ -10,9 +10,11 @@ import {
1010 Dialog ,
1111 ConfirmationDialog ,
1212 LaunchDialog ,
13- TutorialObserver
13+ TutorialObserver ,
1414} from 'netpyne/components' ;
15- import { loadModel } from '../redux/actions/general' ;
15+ import { loadModel , openDialog } from '../redux/actions/general' ;
16+ // import { execPythonMessage } from './general/GeppettoJupyterUtils';
17+ import { replayAll } from './general/CommandRecorder' ;
1618
1719const styles = ( { zIndex } ) => ( {
1820 root : {
@@ -46,6 +48,11 @@ class NetPyNE extends React.Component {
4648 super ( props ) ;
4749 this . openPythonCallDialog = this . openPythonCallDialog . bind ( this ) ;
4850 this . loaded = false ;
51+ this . kernelRestartState = {
52+ state : "idle" ,
53+ kernelID : undefined ,
54+ crashLoop : false
55+ }
4956 }
5057
5158 componentDidMount ( ) {
@@ -66,7 +73,7 @@ class NetPyNE extends React.Component {
6673 return ;
6774 }
6875 this . loaded = true ;
69- console . log ( 'Netpyne is ready' ) ;
76+ console . log ( 'NetPyNE-UI component is ready' ) ;
7077 if ( window !== window . parent ) {
7178 window . parent . postMessage ( {
7279 type : 'APP_READY' ,
@@ -84,7 +91,107 @@ class NetPyNE extends React.Component {
8491 } ;
8592 // A message from the parent frame can specify the file to load
8693 window . addEventListener ( 'message' , loadFromEvent ) ;
87- // window.load = loadFromEvent
94+
95+ // Logic for kernel reinit
96+ const handleKernelRestart = ( { detail : { kernel, type } } ) => {
97+ switch ( this . kernelRestartState . state ) {
98+ case "restarting" :
99+ if ( type === "kernel_ready" || type === "kernel_autorestarting" ) {
100+ console . log ( "Replaying all commands since the beginning of the session" )
101+ replayAll ( this . kernelRestartState . kernelID )
102+ this . kernelRestartState = {
103+ ...this . kernelRestartState ,
104+ state : "idle" ,
105+ kernelID : undefined ,
106+ }
107+ }
108+ case "idle" :
109+ if ( type === "kernel_connected" ) {
110+ console . log ( "Kernel is connecting/starting, being init" )
111+ this . kernelRestartState = {
112+ ...this . kernelRestartState ,
113+ state : "init" ,
114+ kernelID : kernel . id
115+ }
116+ }
117+ else if ( type === "kernel_autorestarting" ) {
118+ console . log ( "Kernel restart event caught, trying to re-init the current model" )
119+ this . kernelRestartState = {
120+ ...this . kernelRestartState ,
121+ state : "restarting" ,
122+ kernelID : kernel . id
123+ }
124+ if ( ! this . kernelRestartState . crashLoop ) {
125+ this . props . dispatchAction ( openDialog ( {
126+ title : "Kernel restart" ,
127+ message : "An action occured that made the kernel restart. We are reloading your model and all the actions you applied on it."
128+ } ) )
129+ }
130+ }
131+ else if ( type === "kernel_restarting" ) {
132+ console . log ( "Kernel restart, perhaps it's a special restart?" )
133+ this . kernelRestartState = {
134+ ...this . kernelRestartState ,
135+ state : "special_restart" ,
136+ kernelID : kernel . id
137+ }
138+ }
139+ case "init" :
140+ if ( type === "kernel_ready" ) {
141+ console . log ( "Kernel properly initialized" )
142+ this . kernelRestartState = {
143+ ...this . kernelRestartState ,
144+ state : "idle" ,
145+ kernelID : undefined ,
146+ }
147+ }
148+ case "special_restart" :
149+ if ( type == "kernel_autorestarting" ) {
150+ console . log ( "Kernel autorestart after a start, we might not have the ready event, we force it then" )
151+ replayAll ( this . kernelRestartState . kernelID )
152+ this . kernelRestartState = {
153+ ...this . kernelRestartState ,
154+ state : 'restarting' ,
155+ kernelID : kernel . id ,
156+ }
157+ } else {
158+ console . log ( "Regular restart detected" )
159+ this . kernelRestartState = {
160+ ...this . kernelRestartState ,
161+ state : 'idle' ,
162+ kernelID : undefined ,
163+ }
164+ }
165+ }
166+ }
167+ window . addEventListener ( 'kernelstatus' , handleKernelRestart )
168+
169+ // Dedicated code to handle crash loops
170+ const kernelRestartLoopHandler = ( ) => {
171+ if ( ! this . kernelRestartState . crashLoop ) {
172+ this . props . dispatchAction ( openDialog ( {
173+ title : "Kernel restart loop stabilization" ,
174+ message : "One of your actions triggered a kernel restart loop. We are trying to identify the faulty command and to restore your model until this point. Close this window and wait for the kernel stabilization notification."
175+ } ) )
176+ } else {
177+ clearTimeout ( this . kernelRestartState . crashLoop )
178+ }
179+ const taskID = setTimeout ( ( _this ) => {
180+ this . props . dispatchAction ( openDialog ( {
181+ title : "Kernel restart loop stabilized" ,
182+ message : "The kernel is now stabilized."
183+ } ) ) ;
184+ this . kernelRestartState = {
185+ ...this . kernelRestartState ,
186+ crashLoop : false
187+ }
188+ } , 8000 , this )
189+ this . kernelRestartState = {
190+ ...this . kernelRestartState ,
191+ crashLoop : taskID
192+ }
193+ }
194+ window . addEventListener ( 'kernelRestartLoop' , kernelRestartLoopHandler )
88195 }
89196
90197 componentWillUnmount ( ) {
@@ -115,6 +222,9 @@ class NetPyNE extends React.Component {
115222 < div className = { classes . container } >
116223 < div className = { classes . topbar } >
117224 < Topbar />
225+ { /* <button onClick={() => {
226+ execPythonMessage("utils.convertToJS(netpyne_geppetto.importCellTemplate(utils.convertToPython('{\"cellArgs\":{},\"fileName\":\"/home/vince/git-repository/metacell/NetPyNE-UI/workspace/cells/FScell.hoc\",\"cellName\":\"FScell\",\"label\":\"CellType1\",\"modFolder\":\"/home/vince/git-repository/metacell/NetPyNE-UI/workspace/mod\",\"importSynMechs\":false,\"compileMod\":false}')))")
227+ }}>CRASH ME</button> */ }
118228 </ div >
119229 < Box p = { 1 } flex = { 1 } display = "flex" alignItems = "stretch" >
120230 < Grid container spacing = { 1 } className = { classes . content } alignItems = "stretch" >
0 commit comments