Open artforlife opened 6 years ago
This is a common "gotcha" in common lisp.
This is because *handler*
already has a value, the second call using defvar
does nothing.
defvar
defines a global variable, if it already has a value it does nothing more. if does not yet have a value (i.e. unbound), it will evaluate the expression and sets the variable to the result of the expression.
To restart you should use the following:
(setf *handler*
(clack:clackup
(lambda (env)
(declare (ignore env))
'(200 (:content-type "text/plain") ("Hello, Clack!")))))
a bit of advice and an aside. In slime, you can restart common lisp without restarting emacs. At the REPL with a blank prompt, enter ,
(comma), then write restart-inferior-lisp
followed by enter key.
Thanks for the lesson! 👍
If I use this method of restarting the inferior-lisp process, will I lose what has been defined at the Top level?
yes, because you are starting a fresh new common lisp process, you will need to re-load into lisp what you want to work on. Using your example, you will need to reload clack
. The advantage is that emacs maintains all the other buffers open (you will not need to open the files you are working on) and the slime repl will maintain its history.
These three helper procedures might be handy for this case?
;; Using defparameter instead of defconstant
;; to stop SLIME from complaining
;; about re-defining +default-port+.
(defparameter +default-port+ 2500)
(defvar *server-handler* nil)
(defun start-server (&optional (port +default-port+))
(if *server-handler*
(princ "Server is already running. Use restart-server instead?")
(setf *server-handler*
(clack:clackup #'my-server-logic
:port port
:server :hunchentoot))))
(defun stop-server ()
(if *server-handler*
(progn
(clack:stop *server-handler*)
(setf *server-handler* nil)
(princ "Server stopped."))
(princ "Server is not even started yet.")))
(defun restart-server (&optional (port +default-port+))
(if (null *server-handler*)
(princ "Server is not even started yet.")
(progn
(princ "Restarting server..")
(stop-server)
(start-server port))))
What is the cleanest way to stop a server without a handler? I started the server without binding the return value to a variable, so I have no obvious way (as a lisp newbie) of stopping it except to kill common lisp. Is there a better way?
Thanks in advance for responding to this tangential question! This little thread already has some good tidbits for beginners so I figure why not add on...
EDIT: I managed to answer my own question...
Within the REPL, the user can use *
to re-return the previous output. So, if we have started the server and did not bind the returned handler object to a variable, the bare object will be output to the REPL instead. Assuming there aren't any intervening commands, we can then bind this object to a variable with the form: (defvar *server-handler* *)
, where the final *
is a special variable that stands for the previous output. And then we can continue to stop the server as normal: (clack:stop *server-handler*)
.
If there are intervening commands/ouput, this is still quite doable, but you will have to use a different special variable depending on how far back you need to reference. The backreferences section of the SLY documentation will guide you.
I followed the basic instructions on how to Start and Stop the Clack located on the front page of this repo. I discovered that once the server is stopped using:
(clack:stop *handler*)
It is impossible to start it again using:
To start it again, I always need to restart the Emacs. It appears that the
*handler*
variable does not fully capture the running server. Hence, when one stops it and then tries to start the server again on the same port, there are still some remnants of the previous instance present.