Restart if kernel still alive needs to work

This commit is contained in:
dickmao 2018-11-01 20:08:10 -04:00
parent d621944797
commit db2856f445
7 changed files with 77 additions and 49 deletions

View file

@ -17,5 +17,11 @@ Scenario: kernel restart succeeds
And I press "C-c C-r"
And I wait for the smoke to clear
And header does not say "Kernel requires restart C-c C-r"
And I clear log expr "ein:log-all-buffer-name"
And I force restart kernel
And I switch to log expr "ein:log-all-buffer-name"
Then I should not see "[warn]"
And I should not see "[error]"
And I should see "ein:kernel-start--complete"

View file

@ -8,6 +8,11 @@
(let ((equal-p (string= says (slot-value (slot-value ein:%notification% 'kernel) 'message))))
(cl-assert (if negate (not equal-p) equal-p)))))
(When "I force restart kernel$"
(lambda ()
(ein:notebook-restart-kernel ein:%notebook%)
(And "I wait for the smoke to clear")))
(When "I kill processes like \"\\(.+\\)\"$"
(lambda (substr)
(mapc (lambda (p) (if (search substr (process-name p)) (delete-process p)))

View file

@ -376,6 +376,8 @@ auto-execution mode flag in the connected buffer is `t'.")))
:s2m
'((status_idle.Kernel . nil)
(status_busy.Kernel . "Kernel is busy...")
(status_restarted.Kernel . "Kernel restarted")
(status_restarting.Kernel . "Kernel restarting...")
(status_dead.Kernel . "Kernel requires restart C-c C-r")))
:type ein:notification-status))
"Notification widget for Notebook.")

View file

@ -102,30 +102,32 @@ CALLBACK of arity 0 (e.g., print a message kernel started)"
(assert (and (ein:$notebook-p notebook) (ein:$kernel-p kernel)))
(unless iteration
(setq iteration 0))
(unless (ein:kernel-live-p kernel)
(if (<= (ein:$kernel-api-version kernel) 2)
(error "Api version %s unsupported" (ein:$kernel-api-version kernel))
(let ((kernelspec (ein:$notebook-kernelspec notebook)))
(ein:query-singleton-ajax
(list 'kernel-start (ein:$kernel-kernel-id kernel))
(ein:url (ein:$kernel-url-or-port kernel) "api/sessions")
:type "POST"
:data (json-encode
(cond ((<= (ein:$kernel-api-version kernel) 4)
`(("notebook" .
(("path" . ,(ein:$notebook-notebook-path notebook))))
(if (<= (ein:$kernel-api-version kernel) 2)
(error "Api version %s unsupported" (ein:$kernel-api-version kernel))
(if (ein:kernel-live-p kernel)
(ein:log 'warn "Orphaning live kernel %s" (ein:$kernel-kernel-id kernel)))
(let ((kernelspec (ein:$notebook-kernelspec notebook)))
(ein:query-singleton-ajax
(list 'kernel-start (ein:$kernel-kernel-id kernel))
(ein:url (ein:$kernel-url-or-port kernel) "api/sessions")
:type "POST"
:data (json-encode
(cond ((<= (ein:$kernel-api-version kernel) 4)
`(("notebook" .
(("path" . ,(ein:$notebook-notebook-path notebook))))
,@(if kernelspec
`(("kernel" .
(("name" . ,(ein:$kernelspec-name kernelspec))))))))
(t `(("path" . ,(ein:$notebook-notebook-path notebook))
("type" . "notebook")
,@(if kernelspec
`(("kernel" .
(("name" . ,(ein:$kernelspec-name kernelspec))))))))
(t `(("path" . ,(ein:$notebook-notebook-path notebook))
("type" . "notebook")
,@(if kernelspec
`(("kernel" .
(("name" . ,(ein:$kernelspec-name kernelspec))))))))))
:sync ein:force-sync
:parser #'ein:json-read
:success (apply-partially #'ein:kernel-start--success kernel callback)
:error (apply-partially #'ein:kernel-start--error kernel notebook iteration callback))))))
(("name" . ,(ein:$kernelspec-name kernelspec))))))))))
:sync ein:force-sync
:parser #'ein:json-read
:complete (apply-partially #'ein:kernel-start--complete kernel callback)
:success (apply-partially #'ein:kernel-start--success kernel callback)
:error (apply-partially #'ein:kernel-start--error kernel notebook iteration callback)))))
(defun ein:kernel-restart (kernel)
"Will not restart kernel if kernel doesn't have a session-id.
@ -134,12 +136,26 @@ Kernel can be dead (as in the websocket died unexpectedly) but must be fully-for
(ein:kernel-delete kernel
(apply-partially
(lambda (kernel* notebook)
(ein:events-trigger (ein:$kernel-events kernel*)
'status_restarting.Kernel)
(ein:kernel-start kernel* notebook 0 (lambda () (message "Kernel restarted"))))
(if (ein:kernel-live-p kernel*)
(ein:log 'error "Kernel %s still live!" (ein:$kernel-kernel-id kernel*))
(ein:events-trigger (ein:$kernel-events kernel*)
'status_restarting.Kernel)
(ein:kernel-start kernel* notebook 0
(apply-partially
(lambda (nb)
(with-current-buffer (ein:notebook-buffer nb)
(ein:notification-status-set
(slot-value ein:%notification% 'kernel)
'status_restarted.Kernel)))
notebook))))
kernel (ein:get-notebook-or-error))))
(cl-defun ein:kernel-start--error (kernel notebook iteration callback &key error-thrown sybmol-status &allow-other-keys)
(defun* ein:kernel-start--complete (kernel callback &key data response
&allow-other-keys
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
(ein:log 'debug "ein:kernel-start--complete %s" resp-string))
(defun* ein:kernel-start--error (kernel notebook iteration callback &key error-thrown sybmol-status &allow-other-keys)
(let* ((max-tries 3)
(tries-left (1- (- max-tries iteration))))
(ein:log 'verbose "ein:kernel-start--error [%s], %s tries left"
@ -152,9 +168,8 @@ Kernel can be dead (as in the websocket died unexpectedly) but must be fully-for
(if (plist-get data :kernel)
(setq data (plist-get data :kernel)))
(destructuring-bind (&key id &allow-other-keys) data
(unless id
(error "ein:kernel-start--success: No :id property in %S." data))
(ein:log 'verbose "Kernel started: %s" id)
(ein:log 'verbose "ein:kernel-start--success: kernel-id=%s session-id=%s"
id session-id)
(setf (ein:$kernel-kernel-id kernel) id)
(setf (ein:$kernel-session-id kernel) session-id)
(setf (ein:$kernel-ws-url kernel) (ein:kernel--ws-url (ein:$kernel-url-or-port kernel)))
@ -549,14 +564,14 @@ Example::
(ein:log 'info "Sent interruption command.")))))
(defun ein:kernel-delete (kernel &optional callback)
"CALLBACK of arity 0 (e.g., kernel restart)"
"Regardless of success or error, we clear all state variables of kernel and funcall CALLBACK of arity 0 (e.g., kernel restart)"
(ein:and-let* ((kernel kernel)
(session-id (ein:$kernel-session-id kernel)))
(ein:query-singleton-ajax
(list 'kernel-delete session-id)
(ein:url (ein:$kernel-url-or-port kernel) "api/sessions" session-id)
:type "DELETE"
:complete (apply-partially #'ein:kernel-delete--complete session-id callback)
:complete (apply-partially #'ein:kernel-delete--complete kernel session-id callback)
:error (apply-partially #'ein:kernel-delete--error session-id callback)
:success (apply-partially #'ein:kernel-delete--success session-id callback))))
@ -568,13 +583,14 @@ Example::
(defun* ein:kernel-delete--success (session-id callback &key data symbol-status response
&allow-other-keys)
(ein:log 'verbose "ein:kernel-delete--success: %s deleted" session-id)
(when callback (funcall callback)))
(ein:log 'verbose "ein:kernel-delete--success: %s deleted" session-id))
(defun* ein:kernel-delete--complete (session-id callback &key data response
&allow-other-keys
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
(ein:log 'debug "ein:kernel-delete--complete %s" resp-string))
(defun* ein:kernel-delete--complete (kernel session-id callback &key data response
&allow-other-keys
&aux (resp-string (format "STATUS: %s DATA: %s" (request-response-status-code response) data)))
(ein:log 'debug "ein:kernel-delete--complete %s" resp-string)
(ein:kernel-disconnect kernel)
(when callback (funcall callback)))
;; Reply handlers.
@ -669,7 +685,7 @@ Example::
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: msg_type=%s msg_id=%s"
msg-type msg-id)
(if (and (not (equal msg-type "status")) (null callbacks))
(ein:log 'verbose "Got message not from this notebook.")
(ein:log 'verbose "Not processing msg_type=%s msg_id=%s" msg-type msg-id)
(ein:case-equal msg-type
(("stream" "display_data" "pyout" "pyerr" "error" "execute_result")
(ein:aif (plist-get callbacks :output)
@ -686,8 +702,8 @@ Example::
(ein:log 'verbose (format "Received data_pub message w/content %s" packet)))
(("clear_output")
(ein:aif (plist-get callbacks :clear_output)
(ein:funcall-packed it content metadata)))))))))
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: finished")
(ein:funcall-packed it content metadata))))))))
(ein:log 'debug "KERNEL--HANDLE-IOPUB-REPLY: finished"))
;;; Utility functions

View file

@ -58,7 +58,7 @@ S-mouse-1/3 (Shift + left/right click): move this tab to left/right"
(let* ((message (cdr (assoc status (slot-value ns 's2m)))))
(setf (slot-value ns 'status) status)
(setf (slot-value ns 'message) message)
(force-mode-line-update)))
(force-mode-line-update t)))
(defmethod ein:notification-bind-events ((notification ein:notification)
events)
@ -94,11 +94,9 @@ where NS is `:kernel' or `:notebook' slot of NOTIFICATION."
notification)
(ein:events-on events
'status_restarting.Kernel
#'ein:notification--fadeout-callback
(list (slot-value notification 'kernel)
"Restarting kernel..."
'status_restarting.Kernel
'status_idle.Kernel)))
#'ein:notification--callback
(list (slot-value notification 'kernel)
'status_restarting.Kernel)))
(defun ein:notification--callback (packed data)
(let ((ns (car packed))

View file

@ -93,7 +93,7 @@
:on-message on-message
:on-close on-close
:on-error (lambda (ws action err)
(ein:log 'error "WS action [%s] %s (%s)"
(ein:log 'info "WS action [%s] %s (%s)"
err action (websocket-url ws)))))
(websocket (make-ein:$websocket :ws ws :kernel kernel :closed-by-client nil)))
(setf (websocket-client-data ws) websocket)

View file

@ -59,9 +59,10 @@
notebook_create_checkpoint.Notebook
notebook_checkpoint_created.Notebook
execution_count.Kernel
status_restarting.Kernel
status_idle.Kernel
status_busy.Kernel
status_restarting.Kernel
status_restarted.Kernel
status_dead.Kernel
))
(callbacks (oref events :callbacks)))