From f98df5b2c45b158589474273068cbceac1282d34 Mon Sep 17 00:00:00 2001 From: anatoly Date: Wed, 23 Dec 2015 11:04:47 -0500 Subject: [PATCH] #22, #25, #26: states with no :stop are restarted on ns recompile --- README.md | 7 +++++-- src/mount/core.cljc | 9 +++++---- test/core/mount/test/cleanup_dirty_states.cljc | 9 +++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 3b9de0d..2c4ef07 100644 --- a/README.md +++ b/README.md @@ -421,13 +421,16 @@ Switched to branch 'suspendable' Mount will detect when a namespace with states (i.e. with `(defstate ...)`) was reloaded/recompiled, and will check every state in this namespace whether it was running at the point of recompilation. If it was, _it will restart it_: -* will invoke its `:stop` function that was there _before_ the recompilation -* will invoke its new `:start` function _after_ this state is recompiled/redefined +* if a state has a `:stop` function, mount will invoke it on the old version of state (i.e. cleanup) +* it will call a "new" `:start` function _after_ this state is recompiled/redefined Mount won't keep it a secret, it'll tell you about all the states that had to be restarted during namespace reload/recompilation: +Providing a `:stop` function _is_ optional, but in case a state needs to be cleaned between restarts or on a system shutdown, +`:stop` is highly recommended. + ## Affected States Every time a lifecycle function (start/stop/suspend/resume) is called mount will return all the states that were affected: diff --git a/src/mount/core.cljc b/src/mount/core.cljc index ac56306..cfeaa0b 100644 --- a/src/mount/core.cljc +++ b/src/mount/core.cljc @@ -48,9 +48,10 @@ this function stops this 'lost' state instance. it is meant to be called by defstate before defining a new state" [state] - (when-let [stop (@running state)] - (prn (str "<< stopping.. " state " (namespace was recompiled)")) - (stop) + (when-let [{:keys [stop] :as up} (@running state)] + (when stop + (prn (str "<< stopping.. " state " (namespace was recompiled)")) + (stop)) (swap! running dissoc state) {:restart? true})) @@ -90,7 +91,7 @@ (record! state resume done) (record! state start done)))] (alter-state! current s) - (swap! running assoc state stop) + (swap! running assoc state {:stop stop}) (update-meta! [state :status] #{:started})))) (defn- down [state {:keys [stop status] :as current} done] diff --git a/test/core/mount/test/cleanup_dirty_states.cljc b/test/core/mount/test/cleanup_dirty_states.cljc index a0d0188..56bc741 100644 --- a/test/core/mount/test/cleanup_dirty_states.cljc +++ b/test/core/mount/test/cleanup_dirty_states.cljc @@ -31,6 +31,15 @@ (mount/stop) (is (instance? mount.core.NotStartedState (dval tapp.example/nrepl)))))) +#?(:clj + (deftest start-on-recompile + (let [_ (mount/start) + before (dval tapp.conf/config)] + (require 'tapp.conf :reload) + (is (not (identical? before (dval tapp.conf/config)))) ;; should be a newly recompiled map + (mount/stop) + (is (instance? mount.core.NotStartedState (dval tapp.conf/config)))))) + #?(:cljs (deftest cleanup-dirty-states (let [_ (mount/start #'mount.test.helper/helper)]