Lisp HUG Maillist Archive

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.


Re: Remote REPL

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


Re: Remote REPL

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



Re: Remote REPL

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.


Re: Remote REPL

Unable to parse email body. Email id is 3953

Re: Remote REPL

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.


Updated at: 2020-12-10 08:52 UTC