mirror of
https://github.com/vale981/emacs-ipython-notebook
synced 2025-03-05 09:01:40 -05:00
Restart if kernel still alive needs to work
This commit is contained in:
parent
d621944797
commit
db2856f445
7 changed files with 77 additions and 49 deletions
|
@ -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"
|
||||
|
||||
|
|
@ -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)))
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)))
|
||||
|
|
Loading…
Add table
Reference in a new issue