tolitius / mount

managing Clojure and ClojureScript app state since (reset)
Eclipse Public License 1.0
1.22k stars 88 forks source link

Why is mount not stopping the states on Ctrl-C? #113

Closed art-solopov closed 4 years ago

art-solopov commented 4 years ago

I'm trying to understand mount and how it plays with states and services (such as an HTTP server). I'm currently having an http-kit server:

(ns clojure-play.play-mt.server
  (:require [org.httpkit.server :refer [run-server]]
            [mount.core :refer [defstate]]))

(defonce a-server (atom nil))

(defn handler [req]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello world!"})

(defn stop-server []
  (when-not (nil? @a-server)
    (println "Stopping server")
    (@a-server :timeout 100)
    (reset! a-server nil)))

(defn start-server []
  (println "Starting server")
  (reset! a-server (run-server handler)))

(defstate server :start (start-server) :stop (stop-server))

And a module using mount to launch it:

(ns clojure-play.play-mt.core
  (:require [mount.core :as mount]
            [mount-up.core :as mu]
            [clojure-play.play-mt.server]))

(mu/on-upndown :info mu/log :before)

(defn -main [& args]
  (mount/start))

Now, I start it with lein run -m clojure-play.play-mt.core, do a couple requests to check the server works, and interrupt it via Ctrl+C. I get those logs:

ноя 29, 2019 1:39:14 PM clojure.tools.logging$eval873$fn__876 invoke
INFO: >> starting.. #'clojure-play.play-mt.server/server
Starting server
^C

Why doesn't mount stop the states on Ctrl+C? Is there something in configuration I'm missing?

tolitius commented 4 years ago

mount does not do anything special on Ctrl+C. On JVM this is usually handled with a shutdown hook. Here is an example:

(defn -main [& args]
  (mu/on-upndown :info mu/log :before)
  (log/info "launching app...")
  (.addShutdownHook (Runtime/getRuntime)
                    (Thread. #(mount/stop)))
  (mount/start))

this will call (mount/stop) on kill -X/Ctrl+C. here are the Java docs for it.

let me know if it helps

art-solopov commented 4 years ago

It works, thank you! But is it an idiomatic way to manage mount state (esp. in production)?

tolitius commented 4 years ago

yes it is. this is not exactly mount specific. if any of components you start need to be stopped on a forceful program exit, such as Ctrl + C / kill -X, you should register a JVM shutdown hook.

art-solopov commented 4 years ago

I see, thank you!