aroemers / mount-lite

mount, but different and light
https://cljdoc.org/d/functionalbytes/mount-lite/
Eclipse Public License 1.0
102 stars 8 forks source link

Reload after changing a def into defstate crashes #8

Closed vizanto closed 8 years ago

vizanto commented 8 years ago

Steps to reproduce

1) Create file

(ns my-namespace (:require [mount.lite]))
(def thing "thing")

(mount.lite/defstate bar :start "bar")
user=> (require 'my-namespace :reload)

2) Edit:

(ns my-namespace (:require [mount.lite]))
(mount.lite/defstate thing :start "thing")

(mount.lite/defstate bar :start "bar")
user=> (require 'my-namespace :reload)
clojure.lang.Compiler$CompilerException: java.lang.NullPointerException, compiling:(my_namespace.clj:2:1)
         java.lang.NullPointerException:
                               ...
   mount.lite.graph/add-same-ns/fn                         graph.clj:   33
                               ...
               clojure.core/reduce                          core.clj: 6518
      mount.lite.graph/add-same-ns                         graph.clj:   30
    mount.lite.graph/var-graph*/fn                         graph.clj:   57
clojure.core.protocols/iter-reduce                     protocols.clj:   49
         clojure.core.protocols/fn                     protocols.clj:  112
       clojure.core.protocols/fn/G                     protocols.clj:   13
aroemers commented 8 years ago

@vizanto You are right, and I know where this issue is caused (here). I will supply a fix soon. For now, a restart (of the JVM) or an (ns-unmap 'my-namespace 'thing) will do the trick.

vizanto commented 8 years ago

true, no rush :+1: thanks

aroemers commented 8 years ago

@vizanto The defstate macro now disallows defining a defstate for an existing non-defstate var, explicitly. If you really need to introduce a new defstate that has dependents, while keeping the JVM running, try this:

;; Unmap the existing var, if it exists.
(ns-unmap 'my-namespace 'thing)
;; Create the defstate.
(defstate thing ...)
;; Ensure the correct order sequence number.
(alter-meta! *1 assoc :mount.lite/order <an-order-number-that-is-between-its-dependents-and-dependencies>)

The mount-library has been incrementing the order sequence number by 10 for some time now, in order to support this scenario.

The explicit disallowance will be released in 0.9.8.