So — after 3 months of using mount with ClojureScript and Clojure, I am now certain that there is a bug somewhere in the interaction between figwheel and mount. My start functions are being called twice. Unfortunately, this is not something I can make into a nicely reproducible minimal test case — it happens in a large application.
@jrychter: hmm.. I don't know figwheel well (I use https://github.com/adzerk-oss/boot-reload mostly). but sure, there can be a bug in the way cljs states are handled. I wonder if figwheel sometimes decides to reload all (not just incremental changes), which would reload mount itself
Yeah, well, I can live with it for the most part. I just hit Command-R more often than usual. Sometimes the app breaks completely, because double-loading of my dispatcher
namespace breaks event handling. I wrote a bit of code to detect this and at least log an error message so that I know what's going on (a one-shot atom reset to true in the start function is used to detect double-loading). Some amount of make clean
and restarting cider+figwheel eventually gets me back to a workable state.
But I just wanted you to know that there is a problem, because if I'm seeing it, then other people might see it too.
definitely, I appreciate that
would be also good to know what the problem is caused by though :simple_smile:
this was one of the many reasons I moved off of lein.. you can never be sure "what overwrote what", but of course there are a lot of great tools build around lein, and they are primarily used. so definitely need to get to the bottom of this..
which state (that is restarted twice) in your use case is most painful to deal with, is that some kind of a web socket?
just "double lading" should not break mount: i.e. states that are started would not be restarted unless their namespace is wiped. but even then they would be stopped first and then restarted
I wonder if you could try ^{:on-reload :noop}
and still see a problem
Well, in this case I wouldn't blame lein itself, as ClojureScript is managed by figwheel in dev environment. The double loading is a problem because I use a dispatcher
pattern, where a single dispatcher with a pub/sub calls event handlers. Every namespace registers a bunch of event handlers. Obviously it's a problem if handlers get registered twice, because they will be called twice. And it's a disaster if the dispatcher start function gets run twice, because that one creates the bus and pub. It basically means losing all subscriptions.
Now I'm afraid of touching that dispatcher.cljs file. If I touch it, things might break…
But I'll try the :on-reload :noop
thing.
The (2)s are next to every namespace that was just reloaded (all fifteen or so). Everything was done twice.
The :on-reload :noop
in dispatcher.cljs doesn't seem to change much. Well, except that after the change my app doesn't even start, because of double-loading. But I have no idea why after some changes it works and after others it doesn't. Even cleaning JavaScript inbetween doesn't help. Back to working version for now.
But perhaps there is some tracing/logging that I could enable to learn more about where the problem is?
> the (2)s are next to every namespace that was just reloaded the only way this would happen (initial thinking) if there is more than a single mount running: i.e. two mounts are looking after their states..
i.e. almost like "two mounts" are brought in (perhaps as deps) and started
do you ever see #'partsbox.core/state
starting twice before any reloads?
@jrychter: try mount-0.1.11-SNAPSHOT.jar
it will log states it mounted / defined
should allow for a better discovery on when the "second" mount comes into play