From 7bce62e2ae6b0c80ef5769b2d7ef7bfa4e43df8b Mon Sep 17 00:00:00 2001 From: Nathaniel Nicandro Date: Fri, 28 Jun 2019 20:07:00 -0500 Subject: [PATCH] `jupyter-create-connection-info` -> `jupyter-local-tcp-conn-info` Also use `jupyter-available-local-ports` to get ports for use. --- jupyter-kernel-manager.el | 68 ++++++++++++++++++++------------------- test/jupyter-test.el | 6 ++-- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/jupyter-kernel-manager.el b/jupyter-kernel-manager.el index 2cd82de..d7765ba 100644 --- a/jupyter-kernel-manager.el +++ b/jupyter-kernel-manager.el @@ -461,18 +461,19 @@ subprocess." (defun jupyter--error-if-no-kernel-info (client) (jupyter-kernel-info client)) -(cl-defun jupyter-create-connection-info (&key - (kernel-name "python") - (transport "tcp") - (ip "127.0.0.1") - (signature-scheme "hmac-sha256") - (key (jupyter-new-uuid)) - (hb-port 0) - (stdin-port 0) - (control-port 0) - (shell-port 0) - (iopub-port 0)) - "Create a connection info plist used to connect to a kernel. +(cl-defun jupyter-local-tcp-conn-info (&key + (kernel-name "python") + (signature-scheme "hmac-sha256") + (key (jupyter-new-uuid)) + (hb-port 0) + (stdin-port 0) + (control-port 0) + (shell-port 0) + (iopub-port 0)) + "Return a connection info plist used to connect to a kernel. + +The :transport key is set to \"tcp\" and the :ip key will be +\"127.0.0.1\". The plist has the standard keys found in the jupyter spec. See http://jupyter-client.readthedocs.io/en/latest/kernels.html#connection-files. @@ -483,25 +484,27 @@ port for that channel." (error "Only hmac-sha256 signing is currently supported")) (append (list :kernel_name kernel-name - :transport transport - :ip ip) + :transport "tcp" + :ip "127.0.0.1") (when (> (length key) 0) (list :signature_scheme signature-scheme :key key)) - (cl-loop - with sock = (zmq-socket (zmq-current-context) zmq-REP) - with addr = (concat transport "://" ip) - for (channel . port) in `((:hb_port . ,hb-port) - (:stdin_port . ,stdin-port) - (:control_port . ,control-port) - (:shell_port . ,shell-port) - (:iopub_port . ,iopub-port)) - collect channel and - if (= port 0) do (setq port (zmq-bind-to-random-port sock addr)) - and collect port else collect port - finally - (zmq-socket-set sock zmq-LINGER 0) - (zmq-close sock)))) + (let ((ports (jupyter-available-local-ports + (cl-loop + with nports = 0 + for p in (list hb-port stdin-port + control-port shell-port + iopub-port) + when (zerop p) do (cl-incf nports) + finally return nports)))) + (cl-loop + for (channel . port) in `((:hb_port . ,hb-port) + (:stdin_port . ,stdin-port) + (:control_port . ,control-port) + (:shell_port . ,shell-port) + (:iopub_port . ,iopub-port)) + collect channel and if (= port 0) + collect (pop ports) else collect port)))) (defun jupyter-start-new-kernel (kernel-name &optional client-class) "Start a managed Jupyter kernel. @@ -531,17 +534,16 @@ command on the host." (let* ((spec (jupyter-guess-kernelspec kernel-name)) (kernel (if (file-remote-p default-directory) (jupyter-command-kernel :spec spec) - (let* ((key (jupyter-new-uuid)) - (conn-info (jupyter-create-connection-info - :kernel-name kernel-name - :key key))) + (let ((key (jupyter-new-uuid))) (jupyter-spec-kernel :spec spec ;; TODO: Convert `jupyter-session' into an object and ;; only require `conn-info'. :session (jupyter-session :key key - :conn-info conn-info))))) + :conn-info (jupyter-local-tcp-conn-info + :kernel-name kernel-name + :key key)))))) (manager (jupyter-kernel-manager :kernel kernel))) (jupyter-start-kernel manager) (let ((client (jupyter-make-client manager client-class))) diff --git a/test/jupyter-test.el b/test/jupyter-test.el index d00d6f1..2a2050e 100644 --- a/test/jupyter-test.el +++ b/test/jupyter-test.el @@ -621,7 +621,7 @@ (ert-deftest jupyter-kernel-lifetime () :tags '(kernel) - (let* ((conn-info (jupyter-create-connection-info)) + (let* ((conn-info (jupyter-local-tcp-conn-info)) (kernel (jupyter-spec-kernel :spec (jupyter-guess-kernelspec "python") :session (jupyter-session @@ -632,7 +632,7 @@ (should (jupyter-kernel-alive-p kernel)) (jupyter-kill-kernel kernel) (should-not (jupyter-kernel-alive-p kernel)) - (setq conn-info (jupyter-create-connection-info)) + (setq conn-info (jupyter-local-tcp-conn-info)) (ert-info ("`jupyter-kernel-manager'") ;; TODO: Should the manager create a session if one isn't present? (oset kernel session (jupyter-session @@ -733,7 +733,7 @@ (skip-unless (not (memq system-type '(ms-dos windows-nt cygwin)))) (let (file fun) (let* ((session (jupyter-session - :conn-info (jupyter-create-connection-info))) + :conn-info (jupyter-local-tcp-conn-info))) (client (jupyter-kernel-client)) (hook (copy-sequence kill-emacs-hook))) (setq file (jupyter-write-connection-file session client))