tolitius / mount

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

States using {:on-reload :noop} that are reloaded while running remain stale after manual restart #105

Open krajj7 opened 5 years ago

krajj7 commented 5 years ago

This is a bit of a feature request, since the current behavior does make some sense, but in my opinion it could be improved.

If you have a running state marked {:on-reload :noop} (to prevent auto-restarts), when you reload your code and later manually stop and restart the state, mount will keep starting the old version of the state, rather than using the newly loaded code.

While keeping the old version running is expected (with {:on-reload :noop}), I think it would be really nice if mount would remember the start/stop functions of the most recently loaded version, and use those after the old state was manually stopped. Currently you need to remember to reload only when the state is stopped to make your new code active.

Example REPL session is below. Ideally you'd get the new version of the state at the end (which is what you'd get if the state was stopped when it was redefined).

boot.user=> (require '[mount.core :as mount])

boot.user=> (mount/defstate ^{:on-reload :noop} teststate :start "old version" :stop (println "old version stopped"))
#'boot.user/teststate

boot.user=> (mount/start)
{:started ["#'boot.user/teststate"]}

boot.user=> teststate
"old version"

; simulating code reload by redefining the state
boot.user=> (mount/defstate ^{:on-reload :noop} teststate :start "new version" :stop (println "new version stopped"))
#'boot.user/teststate

boot.user=> (mount/stop)
old version stopped
{:stopped ["#'boot.user/teststate"]}

boot.user=> (mount/start)
{:started ["#'boot.user/teststate"]}

boot.user=> teststate
"old version"
tolitius commented 5 years ago

I believe that :noop should be exactly that: no operation. If life cycle fns need to be updated and applied after reload, it is no longer a :noop.

let me sleep/think on it a little.

thanks for catching this.