Reputation: 85392
A Clojure-based project of mine uses the netty (required by aleph) web server. I start the server, along with other components, in a web.clj
file like this:
(ns myproject.web)
(def server (atom nil))
(defn initialize []
(if @server
(println "Warning: already initialized")
(let [port 8001]
(println (format "Starting http://localhost:%s/" port))
(swap! server (fn [_] (start-http-server
(wrap-ring-handler app-routes)
{:port port}))))))
(defn shutdown []
(when @server
(do
(println "Shutting down web server")
(@server)
(swap! server (fn [_] nil)))))
(defn reinitialize []
"Run this on the REPL to reload web.clj and restart the web server"
(myproject.web/shutdown)
(use :reload-all 'myproject.web)
(myproject.web/initialize))
The server instance is stored in a Clojure atom, so that it can be stopped later.
I use Emacs and Swank to directly launch the server on the REPL like this (after compiling web.clj
with C-c C-k
):
user> (myproject.web/initialize)
Whenever web.clj
or other dependent modules are edited, I must
remember NOT to recompile web.clj
using C-c C-k because the atom holding the running instance would vanish (due to the atom from a newly compiled module) from the REPL.
Run (myproject.web/reinitialize)
which stops the server and then reloads the module before starting it again.
There are two problems with this:
Often I forget point #1 and press C-c C-k
anyway. This causes the loss of server atom in REPL, leading to having to kill swank (or restart emacs) so that I can start the server at the same port number.
:reload-all
doesn't report compile errors as friendly as C-c C-k
(ugly traceback vs concise clickable errors).
How can I best address these two problems in this edit-compile-restart workflow?
Upvotes: 6
Views: 925
Reputation: 49329
You can replace
(def server (atom nil))
with
(defonce server (atom nil))
that way when you evaluate the buffer it will not redefine server.
Upvotes: 7
Reputation: 91554
for your first problem you can store the atom in a different namespace and on load only overwrite it if it is not yet defined. putting it in it's own namepspace will prevent it from being erased by the reload-all
Upvotes: 2