From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alex Kost Subject: Re: [PATCH] emacs: Use socket instead of port. Date: Tue, 15 Dec 2015 12:33:45 +0300 Message-ID: <87oadscayu.fsf@gmail.com> References: <87y4d08304.fsf@gmail.com> <87poybzgl5.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:45087) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a8lzQ-00021J-H8 for guix-devel@gnu.org; Tue, 15 Dec 2015 04:33:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a8lzP-0008UV-25 for guix-devel@gnu.org; Tue, 15 Dec 2015 04:33:48 -0500 In-Reply-To: <87poybzgl5.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Sat, 12 Dec 2015 19:07:02 +0100") List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: Ludovic =?utf-8?Q?Court=C3=A8s?= Cc: guix-devel@gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Ludovic Court=C3=A8s (2015-12-12 21:07 +0300) wrote: > Alex Kost skribis: > >> There is one small thing though: Guile does not remove socket file after >> exiting from "guile --listen=3D/tmp/foo" so these dead sockets will stay= in >> /tmp dir. As there is no `comint-exit-hook' or alike, I don't see how a >> socket file can be removed after the REPL is killed. > > You could maybe arrange to have Guile run something like: > > (dynamic-wind > (const #t) > (lambda () > (start-repl)) ;start a new REPL > (lambda () > (false-if-exception (delete-file "/tmp/foo")))) > > Not perfect, but I don=E2=80=99t have a better idea. Hm, but it doesn't delete the socket after the quit, right? At least, it doesn't when I tried "guile -l /tmp/repl-server.scm" with the following "/tmp/repl-server.scm": --=-=-= Content-Type: text/x-scheme Content-Disposition: inline; filename=repl-server.scm (use-modules (system repl server)) (let ((socket "/tmp/s1")) (call-with-new-thread (lambda () (dynamic-wind (const #t) (lambda () (run-server (make-unix-domain-server-socket #:path socket))) (lambda () (false-if-exception (delete-file socket))))))) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable And after ",q" the file "/tmp/s1" stayed. > It may be good to fix it upfront though. WDYT? Sorry, I don't understand. Do you mean to fix it "upstream" =E2=80=94 i.e.= , in guile? If so, I agree as it sounds natural to me if guile will delete a socket file it created. Anyway, as I mentioned in the reply to Florian, I think the best would be to add a procedure for deleting socket file to `kill-emacs-hook' (as in the attached updated patch). This should prevent appearing dead sockets. P.S. Maybe it's a wrong impression, but it looks (to me) that connecting to a socket is significantly faster than using a port (so all this Guix REPL stuff starts faster). --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-emacs-Use-socket-instead-of-port.patch >From d6903c7c115809cf88f892e78785d920ff80184d Mon Sep 17 00:00:00 2001 From: Alex Kost Date: Sat, 12 Dec 2015 11:23:03 +0300 Subject: [PATCH] emacs: Use socket instead of port. Suggested by Florian Paul Schmidt. * emacs/guix-backend.el (guix-default-port): Remove. (guix-repl-socket-file-name-function, guix-repl-current-socket): New variables. (guix-repl-socket-file-name, guix-repl-delete-socket-maybe): New procedures. (guix-get-guile-program): Take socket as an optional argument. (guix-start-repl-maybe): Adjust accordingly. --- emacs/guix-backend.el | 68 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/emacs/guix-backend.el b/emacs/guix-backend.el index 82383e4..0736f85 100644 --- a/emacs/guix-backend.el +++ b/emacs/guix-backend.el @@ -36,18 +36,13 @@ ;; running code in the REPL (see ;; ). ;; -;; If you need to use "guix.el" in another Emacs (i.e. when there is -;; a runnig "guile --listen..." REPL somewhere), you can either change -;; `guix-default-port' in that Emacs instance or set -;; `guix-use-guile-server' to t. -;; ;; Guix REPLs (unlike the usual Geiser REPLs) are not added to ;; `geiser-repl--repls' variable, and thus cannot be used for evaluating ;; while editing scm-files. The only purpose of Guix REPLs is to be an ;; intermediate between "Guix/Guile level" and "Emacs interface level". ;; That being said you can still want to use a Guix REPL while hacking -;; auxiliary scheme-files for "guix.el". You can just use "M-x -;; connect-to-guile" (connect to "localhost" and `guix-default-port') to +;; auxiliary scheme-files for "guix.el". You can just use +;; `geiser-connect-local' command with `guix-repl-current-socket' to ;; have a usual Geiser REPL with all stuff defined by "guix.el" package. ;;; Code: @@ -98,11 +93,17 @@ REPL while some packages are being installed/removed in the main REPL." :type 'boolean :group 'guix-repl) -(defcustom guix-default-port 37246 - "Default port used if `guix-use-guile-server' is non-nil." - :type 'integer +(defcustom guix-repl-socket-file-name-function + #'guix-repl-socket-file-name + "Function used to define a socket file name used by Guix REPL. +The function is called without arguments." + :type '(choice (function-item guix-repl-socket-file-name) + (function :tag "Other function")) :group 'guix-repl) +(defvar guix-repl-current-socket nil + "Name of a socket file used by the current Guix REPL.") + (defvar guix-repl-buffer nil "Main Geiser REPL buffer used for communicating with Guix. This REPL is used for processing package actions and for @@ -139,17 +140,28 @@ See `guix-eval-in-repl' for details.") "Message telling about successful Guix operation." (message "Guix operation has been performed.")) -(defun guix-get-guile-program (&optional internal) +(defun guix-get-guile-program (&optional socket) "Return a value suitable for `geiser-guile-binary'." - (if (or internal - (not guix-use-guile-server)) + (if (null socket) guix-guile-program (append (if (listp guix-guile-program) guix-guile-program (list guix-guile-program)) - ;; Guile understands "--listen=..." but not "--listen ..." - (list (concat "--listen=" - (number-to-string guix-default-port)))))) + (list (concat "--listen=" socket))))) + +(defun guix-repl-socket-file-name () + "Return a name of a socket file used by Guix REPL." + (make-temp-name + (concat (file-name-as-directory temporary-file-directory) + "guix-repl-"))) + +(defun guix-repl-delete-socket-maybe () + "Delete `guix-repl-current-socket' file if it exists." + (and guix-repl-current-socket + (file-exists-p guix-repl-current-socket) + (delete-file guix-repl-current-socket))) + +(add-hook 'kill-emacs-hook 'guix-repl-delete-socket-maybe) (defun guix-start-process-maybe (&optional start-msg end-msg) "Start Geiser REPL configured for Guix if needed. @@ -176,19 +188,21 @@ display messages." (get-buffer-process repl)) (and start-msg (message start-msg)) (setq guix-repl-operation-p nil) - (let ((geiser-guile-binary (guix-get-guile-program internal)) - (geiser-guile-init-file (or internal guix-helper-file)) + (unless internal + ;; Guile leaves socket file after exit, so remove it if it + ;; exists (after the REPL restart). + (guix-repl-delete-socket-maybe) + (setq guix-repl-current-socket + (and guix-use-guile-server + (or guix-repl-current-socket + (funcall guix-repl-socket-file-name-function))))) + (let ((geiser-guile-binary (guix-get-guile-program + (unless internal + guix-repl-current-socket))) + (geiser-guile-init-file (unless internal guix-helper-file)) (repl (get-buffer-create (guix-get-repl-buffer-name internal)))) - (condition-case err - (guix-start-repl repl - (and internal - (geiser-repl--read-address - "localhost" guix-default-port))) - (text-read-only - (error (concat "Couldn't start Guix REPL. Perhaps the port %s is busy.\n" - "See buffer '%s' for details") - guix-default-port (buffer-name repl)))) + (guix-start-repl repl (and internal guix-repl-current-socket)) (set repl-var repl) (and end-msg (message end-msg)) (unless internal -- 2.6.3 --=-=-=--