@@ -59,10 +59,17 @@ def __del__(self):
5959 def session_exists (self , path ):
6060 """Check to see if the session of a given name exists"""
6161 self .cursor .execute ("SELECT * FROM session WHERE path=?" , (path ,))
62- reply = self .cursor .fetchone ()
63- if reply is None :
62+ row = self .cursor .fetchone ()
63+ if row is None :
6464 return False
6565 else :
66+ # Note, although we found a row for the session, the associated kernel may have
67+ # been culled or died unexpectedly. If that's the case, we should delete the
68+ # row, thereby terminating the session. This can be done via a call to
69+ # row_to_model that tolerates that condition. If row_to_model returns None,
70+ # we'll return false, since, at that point, the session doesn't exist anyway.
71+ if self .row_to_model (row , tolerate_culled = True ) is None :
72+ return False
6673 return True
6774
6875 def new_session_id (self ):
@@ -198,15 +205,25 @@ def update_session(self, session_id, **kwargs):
198205 query = "UPDATE session SET %s WHERE session_id=?" % (', ' .join (sets ))
199206 self .cursor .execute (query , list (kwargs .values ()) + [session_id ])
200207
201- def row_to_model (self , row ):
208+ def row_to_model (self , row , tolerate_culled = False ):
202209 """Takes sqlite database session row and turns it into a dictionary"""
203210 if row ['kernel_id' ] not in self .kernel_manager :
204- # The kernel was killed or died without deleting the session.
211+ # The kernel was culled or died without deleting the session.
205212 # We can't use delete_session here because that tries to find
206- # and shut down the kernel.
213+ # and shut down the kernel - so we'll delete the row directly.
214+ #
215+ # If caller wishes to tolerate culled kernels, log a warning
216+ # and return None. Otherwise, raise KeyError with a similar
217+ # message.
207218 self .cursor .execute ("DELETE FROM session WHERE session_id=?" ,
208219 (row ['session_id' ],))
209- raise KeyError
220+ msg = "Kernel '{kernel_id}' appears to have been culled or died unexpectedly, " \
221+ "invalidating session '{session_id}'. The session has been removed." .\
222+ format (kernel_id = row ['kernel_id' ],session_id = row ['session_id' ])
223+ if tolerate_culled :
224+ self .log .warning (msg + " Continuing..." )
225+ return None
226+ raise KeyError (msg )
210227
211228 model = {
212229 'id' : row ['session_id' ],
0 commit comments