Fork me on GitHub
#mount
<
2016-04-26
>
jrychter14:04:48

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.

tolitius15:04:39

@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

jrychter15:04:26

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.

jrychter15:04:54

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.

tolitius15:04:29

definitely, I appreciate that

tolitius15:04:47

would be also good to know what the problem is caused by though simple_smile

tolitius15:04:17

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..

tolitius15:04:03

which state (that is restarted twice) in your use case is most painful to deal with, is that some kind of a web socket?

tolitius15:04:56

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

tolitius15:04:22

I wonder if you could try ^{:on-reload :noop} and still see a problem

jrychter17:04:55

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.

jrychter17:04:20

Now I'm afraid of touching that dispatcher.cljs file. If I touch it, things might break…

jrychter17:04:02

But I'll try the :on-reload :noop thing.

jrychter17:04:59

The (2)s are next to every namespace that was just reloaded (all fifteen or so). Everything was done twice.

jrychter17:04:12

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.

jrychter17:04:41

But perhaps there is some tracing/logging that I could enable to learn more about where the problem is?

tolitius19:04:00

> 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..

tolitius19:04:54

i.e. almost like "two mounts" are brought in (perhaps as deps) and started

tolitius20:04:19

do you ever see #'partsbox.core/state starting twice before any reloads?

tolitius20:04:26

@jrychter: try mount-0.1.11-SNAPSHOT.jar it will log states it mounted / defined

tolitius20:04:02

should allow for a better discovery on when the "second" mount comes into play