How to reload (stop and start) an http-kit "mount state" on a -main function

1.4k views Asked by At

With the mount library, how do I reload (stop and start) an http-kit "mount state" on a -main function?

My current code is this:

(defstate server-config :start {:port 7890 :join? false})
(defn start-server [server-config]
  (when-let [server (run-server myserv-ring-handler server-config)]
    (println "Server has started!")
    server))

(defstate myserv-server :start (start-server server-config)
          :stop  (myserv-server :timeout 100))

(defn system-port [args]
  (Integer/parseInt
    (or (System/getenv "PORT")
        (first args)
        "7890")))

(defn -main [& args]
  (mount/start-with-states
    {#'myserv/server-config
     {:start #(array-map :port (system-port args)
                         :join? false)}}))

So when I "lein run" everything works, but whenever I change a file, and the http-kit server is stopped, the command stops. For the moment I'm doing "while true; do lein run; done" to work, so I've thought about adding an infinite loop to the -main function, but it doesn't feel like this is the right way.

How should I do this?

2

There are 2 answers

0
AticusFinch On BEST ANSWER

So I had a couple of separate problems:

  • I didn't understand that now I didn't need to use lein run, but instead I could just do lein repl and start the server from there. The restarting problem is avoided that way.
  • The other one was that I was misusing start-with-states instead of a config state.

You can see a discussion about this with the author of the library here.

1
Scott On

I would suggest adding some metadata to your http server defstate.

From the mount readme:

In case nothing needs to be done to a running state on reload / recompile / redef, set :on-reload to :noop:.

So try something like this:

(defstate ^{:on-reload :noop}
          myserv-server
          :start (start-server server-config)
          :stop  (my-stop-func myserv-server))

This means that when you change a file, the affected code will be reloaded, but the http server will continue to run.

I hope that I've correctly understood your question and that this is what you wanted.

Could I also suggest that if you want to get up and running quickly, then there are various templated web app projects for Leiningen. For example, the Luminus project. You can pass an +http-kit parameter to the lein new luminus myapp command and that will wire up an app correctly for you. You can then go and read the generated code and learn how it all fits together.