Remote REPL
Hi! I'm looking for a simple remote REPL for LW that I can hook into a delivered program and reach via TCP/IP. I'm sure several people have written something like this already so I'm asking here before I re-invent the wheel. TIA, Edi.
Hi! I'm looking for a simple remote REPL for LW that I can hook into a delivered program and reach via TCP/IP. I'm sure several people have written something like this already so I'm asking here before I re-invent the wheel. TIA, Edi.
On 06.06.2005, at 14:20, Edi Weitz wrote: > Hi! > > I'm looking for a simple remote REPL for LW that I can hook into a > delivered program and reach via TCP/IP. I'm sure several people have > written something like this already so I'm asking here before I > re-invent the wheel. > Hi Edi, is the built-in server good enough for your purposes? From the LispWorks Reference Manual: > > Examples > The following example uses the built-in Lisp listener server: > (comm:start-up-server :service 10243) > It makes a Lisp listener server on port 10243 (check with local > network managers that this port number is safe to use). When a client > connects to this, Lisp calls read . The client should send a string > using Common Lisp syntax followed by a newline. This string is used to > name a new light-weight process that runs a Lisp listener. When this > has been created, the server waits for more connections. David
On 06 Jun 2005, at 11:20, Edi Weitz wrote: > Hi! > > I'm looking for a simple remote REPL for LW that I can hook into a > delivered program and reach via TCP/IP. I'm sure several people have > written something like this already so I'm asking here before I > re-invent the wheel. > > TIA, > Edi. Hi Edi, This is the code that I used in the past: ;; A Remote REPL for LispWorks ($Id: remote-repl.lisp,v 1.5 2004/12/02 15:19:18 sven Exp $) (defpackage :remote-repl (:use :cl) (:export #:start-remote-repl #:exit) (:documentation "A trivial remote REPL for LispWorks")) (in-package :remote-repl) #+lispworks(require "comm") ;; Remote listener management (defun run-listener (stream id) "Run a top-level listener" (unwind-protect (progn (format *terminal-io* "~&Start of top level listener ~d~%" id) (format stream "~&Welcome to ~a ~a~%" (lisp-implementation- type) (lisp-implementation-version)) (format stream "This is remote read-eval-print loop ~d, use (remote-repl:exit) to stop~%" id) (system::listener-top-level stream)) (format *terminal-io* "~&End of top level listener ~d, closing stream, ending process~%" id) (close stream))) (defvar *counter* 0) (defun make-stream-and-run-listener (socket-handle) "Function to be used as :function parameter to comm:start-up- server (allows local connections only)" (if (eql (comm:get-socket-address socket-handle) (comm:get-socket-peer-address socket-handle)) (let* ((socket-stream (make-instance 'comm:socket-stream :socket socket-handle :direction :io :element-type 'base-char)) (id (incf *counter*))) (mp:process-run-function (format nil "top-level-listener-~d" id) () #'run-listener socket-stream id)) (progn (format *terminal-io* "~&Non-local connection refused~%") (comm::close-socket socket-handle)))) (defun start-remote-repl (&optional (port 24365)) "Start up a server that accepts remote (localhost only) listener connections" (format *terminal-io* "~&Starting a remote REPL service on port ~d~ %" port) (comm:start-up-server :function #'make-stream-and-run-listener :process-name "remote-repl-server" :service port)) (defun kill-current-process () (format *standard-output* "~&Bye.~%") (mp:process-kill mp:*current-process*)) (defun exit () "Exit this REPL by killing the current process" (kill-current-process)) ;; eof But recently I stopped using it, because the REPL loop itself (which is actually LW's) behaved a bit strange sometimes: in particular it didn't handle the condition well where you just kill (or forget about) the connection, and this is dangerous for a production server. Now I am using screen over a normal tty image startup: that's less (no) extra code and it works at least as well. HTH, Sven
On Mon, 6 Jun 2005 15:50:49 +0500, David Tolpin <dvd@davidashen.net> wrote: > is the built-in server good enough for your purposes? From the > LispWorks Reference Manual: > >> Examples >> The following example uses the built-in Lisp listener server: >> (comm:start-up-server :service 10243) It makes a Lisp listener >> server on port 10243 (check with local network managers that this >> port number is safe to use). When a client connects to this, Lisp >> calls read . The client should send a string using Common Lisp >> syntax followed by a newline. This string is used to name a new >> light-weight process that runs a Lisp listener. When this has been >> created, the server waits for more connections. Thanks David, I must have missed this one. (My excuse is that it is kind of nicely hidden within the docs... :) Yes, this is basically what I'm looking for. I was wondering how I could leave this listener and remove its associated process but it seems that calling LW:QUIT does the job, i.e. in my tests it didn't exit the whole image but just closed the listener. Thanks again, Edi.
Unable to parse email body. Email id is 3953
On Mon, 6 Jun 2005 13:05:57 +0200, Sven Van Caekenberghe <sven@beta9.be> wrote: > This is the code that I used in the past: > > [...] Thanks. Didn't you know about the built-in remote REPL that was just mentioned elsewhere in this thread (like me) or did you have other reasons to write this yourself? > Now I am using screen over a normal tty image startup: that's less > (no) extra code and it works at least as well. Yes, I'm using detachtty all the time on my own servers. But I'm looking for a solution for delivered code - it is not supposed to start up with a REPL. Thanks, Edi.