I've just started development of a service in Clojure. I'm a little lost in how to approach server shutdown.
I'm using Clojure 1.5.1. For logging, I'm using Timbre 1.5.3. I want to embed NREPL into my server for hot code deployment.
This is my core.clj file. Core is my main and I'm using the app shell that "lein new app" generates.
(ns extenium.core
(:require [taoensso.timbre :as t]
[clojure.tools.nrepl.server :as nrs])
(:gen-class))
(def nrepl-server)
(defn start-nrepl-server []
(t/info "Starting nrepl server on port 8628")
(alter-var-root #'nrepl-server
(constantly
(nrs/start-server :port 8628)))
(t/info "Started nrepl server"))
(defn stop-nrepl-server []
(t/info "Stopping nrepl server")
(nrs/stop-server nrepl-server)
(t/info "Stopped nrepl server"))
(defn start []
(alter-var-root #'*read-eval*
(constantly
false))
(start-nrepl-server))
(defn stop []
(stop-nrepl-server))
(defn -main [& args]
(start))
When I "lein run" the nrepl-server starts as expected, with info messages going to the Terminal. I then connect with "nrepl" from Emacs. No problem. From Emacs I execute "(extenium.core/stop)". At that point, I get the "Stopping nrepl server" message on Emacs (meaning that stdout was redirected to the client). The connection closes (as expected) and I never see the "Stopped nrepl server" message. Fine.
I look at the Terminal and I don't see the "Stopping..." or "Stopped..." messages. Instead, I get the following exception:
Exception in thread "nREPL-worker-0" java.lang.Error: java.net.SocketException: Socket closed
Ideally, I want the following:
- To be able to initiate shutdown from an NREPL client. Gracefully close all NREPL client connections without exception. Shutdown with the logging messages directed towards the Terminal (or eventually, a rotating log file).
- For the duration of the NREPL connection, clone the logging output to both the server (Terminal or log) and to the NREPL output.
- Capture information about incoming NREPL connections, name them, and log connect and disconnect activity.
- Eventually, authenticate incoming NREPL connections.
- Even later, authorize them for actions they perform.