Hi!
I manage different sub-services inside my application using mount, and I want to restart them easily. However, I do not want to restart the nREPL sub-service, since I am connected to the service using that one.
What is the recommended way to exclude that? I tried
(defn stop []
(mount/stop-except #'bwvisu-web.core/nrepl-server))
(defn go
"starts all states defined by defstate"
[]
(start)
:ready)
(defn reset
"stops all states defined by defstate, reloads modified source files, and restarts the states"
[]
(stop)
(tn/refresh :after 'dev/go))
As explained in the readme, but mount still tries to restart the nrepl-server
.Are you calling the correct stop
in reset
?
Another glitch, though probably unrelated, is that my tests (from the tests/ directory) are also being reloaded and "started" (even though there are no mount states there)...
@arnout I litterally copy&pasted the above from my code. The complete file is this:
(ns dev
(:require [mount.core :as mount]
[clojure.tools.namespace.repl :as tn]
[bwvisu-web.core]))
(defn start []
(mount/start))
(defn stop []
(mount/stop-except #'bwvisu-web.core/nrepl-server))
(defn go
"starts all states defined by defstate"
[]
(start)
:ready)
(defn reset
"stops all states defined by defstate, reloads modified source files, and restarts the states"
[]
(stop)
(tn/refresh :after 'dev/go))
Code seems good. Does it really restart the nREPL server? Or does it (try to) start a second instance?
Hm, I don't know. How do I figure that out? I see: #error{:cause "Address already in use (Bind failed)"
Check, it tries to start a second instance
It did no stop the current one
Hm, I think the mistake is much more stupid than I thought...
Could be due to tools.namepace reloading the bwvisu-web.core
namespace, reloading the nrepl-server
defstate as well.
@arnout And I would prevent that by setting :on-reload :noop?
I am using Cursive. I run the application using "Run nREPL with Leiningen". Leiningen is configured to start the nREPL on TCP:9998. I also have the core/nrepl-server
setup to run on TCP:9998. I assume that now both the nREPL started by Cursive/Leiningen and the one started by my application are trying to run on the same port...?
Yeah, that won't work 🙂
Is there a convenient way to fire up the application, start the core/nrepl-server
and make Cursive's REPL connect to it?
The :on-reload
option might help. I'm no expert on mount
(I am on mount-lite
though 😉)
btw, I also experimented with Socket REPL and Tubular, but could not get that to work at all.
There is something even more lightweight than mount?
About the Cursive question; I don't know, I use Emacs.
About the lightweight mount, see for yourself, my opinion is obviously biased.
I'll read the blogpost in a sec.
Shouldn't mount start all states that a particular other state uses? Or will it restrict itself to the states listed in (mount/start #'my-state)
, ignoring all dependencies?
@urzds (mount/start #'my-state)
will only start #'my-state
. (mount/start)
will start all the states in the order of their "usage"
@tolitius Thanks.
in your example above, try start with "except" nrepl, otherwise you starting a new one on top of the one that is already started
hence "Address already in use (Bind failed)"
Yes, we figured that one out. one nREPL server was started by Leiningen, the other by my own code. Hence the trouble.
Different topic: Is there a recommended way to call mount/stop
on exit? I tried using this method (https://stackoverflow.com/questions/11709639/how-to-catch-ctrlc-in-clojure), but for some reason my log/info
messages are not printed anymore, so I don't know whether everything actually shuts down properly.
(.addShutdownHook (Runtime/getRuntime)
(Thread. (fn [] (mount/stop))))
in your -main
@tolitius I tried that. Maybe there is some trouble with the logger being shut down before the rest of the system...
I was using plain clojure.tools.logging
you can add println
into that inner function, or you can add https://github.com/tolitius/mount-up into the mix that will help logging all the mount interactions
I loaded io.aviso/logging, and now I get the output I expected.
great