Paul, no it looks like your good. Basically, you only run the risk if the component in which the go block is defined can be unmounted. A lot of components will never be unmounted during the normal execution of the app. Also, I ran code that creates go blocks in IWillMount for about a month before even realising that this was happening, so you may not even see any noticeable effects - but eventually I hit a bug that was eliminated by killing stale go blocks.
So how do you know if a component can be unmounted? Look at how it gets built. If you can trace it all the way back to the root without any conditional rendering, as in Paul's code, then you're safe (as far as I can tell, at least). In Paul's code, start-app is the root component, which renders world-view, which creates the go block. So the only function that could cause world-view to be unmounted is start-app, but its render function always renders world-view, hence no unmounting. In my own experience digging through the code and testing, I've found that (and David has confirmed this in a comment on the issue tracker) components get unmounted if the function which returns the component (ie the one that calls reify and gets passed to build) is different. Some examples where components get unmounted: *(om/build (get components index) ...)* ; If you change index, the previous component gets unmounted before the new component gets mounted *(om/build (if foo component-1 component-2) ...)* ; If you toggle foo from true to false, then component-1 gets unmounted and component-2 gets mounted *(dom/div nil (when foo (om/build component ...)))* ; If you toggle foo from true to false, then component gets unmounted ;; Don't do this! ;-) *(om/build (fn [props owner] (reify om/IRender (render [_] (dom/div nil "Hello")))) props)* ; This component gets unmounted every time the parent is rendered! Because (fn ...) is DIFFERENT every time! Oops! Also be careful of helper functions that might create components that get recreated every time! So if you have code that's like this, those components will want to clean up after themselves in IWillUnmount. Hope this helps! On 22 June 2014 15:29, Andrew Stoeckley <[email protected]> wrote: > Actually this raises a question: if IWillMount runs repeatedly, > wouldn't the go block inside it get generated every time? Normally I'd > have a single go block living outside the Om stuff, and it listens; > but you'd have multiple go blocks created if they were coded inside > IWillMount, wouldn't you? > > On Sun, Jun 22, 2014 at 10:17 PM, Paul Cowan <[email protected]> wrote: > > I have a go block in IWillMount here that is called periodically on a > > timeout function. > > > > Do I run the risk of having multiple go blocks running? Should I be > killing > > the channel? > > > > Cheers > > > > Paul Cowan > > > > Cutting-Edge Solutions (Scotland) > > > > blog: http://thesoftwaresimpleton.com/ > > website: http://www.cuttingedgesolutionsscotland.com/ > > > > > > On 22 June 2014 15:07, Andrew Stoeckley <[email protected]> wrote: > >> > >> Thanks Daniel and everyone; this has been quite helpful. > >> > >> On Sun, Jun 22, 2014 at 10:00 PM, Daniel Kersten <[email protected]> > >> wrote: > >> > PS: > >> > > >> > My invisible component is a container for the actual root - so I don't > >> > return an empty div, I return (om/build real-root-component app-state > >> > options-passed-to-root) > >> > > >> > > >> > On 22 June 2014 14:58, Daniel Kersten <[email protected]> wrote: > >> >> > >> >> I also use an "invisible" management component to handle updates from > >> >> outside of Om. Works great. > >> >> > >> >> > >> >> If you wrap your root with this component, everything should work > just > >> >> fine, but if you create go blocks inside components that can be > >> >> unmounted, > >> >> you have to remember to kill the go block from IWillUnmount or it > will > >> >> stick > >> >> around after the component is unmounted - if the component gets > mounted > >> >> again, you will have two go blocks running! And while its unmounted, > >> >> accessing owner will cause problems. > >> >> > >> >> The way to fix this (other than avoiding go blocks in components that > >> >> might unmount) is to close the channel being listened on in > >> >> IWillUnmount (if > >> >> this component owns the channel) or use core.async/alt to listen on a > >> >> "kill" > >> >> channel as well as the actual channel if this component does not own > >> >> the > >> >> channel, then simply close the kill channel in IWillUnmount. This way > >> >> go > >> >> blocks only exist while the component is mounted. > >> >> > >> >> > >> >> On 22 June 2014 14:51, Dave Della Costa <[email protected]> > wrote: > >> >>> > >> >>> Sure, the main reason for us is to keep things modular. It makes it > >> >>> simpler to restructure things, since it's just another component. > >> >>> > >> >>> We wrap our root component in this "invisible" component, so it just > >> >>> calls build on the root component itself (that is, the invisible > data > >> >>> listener component becomes the actual root component). > >> >>> > >> >>> (2014/06/22 22:28), Andrew Stoeckley wrote: > >> >>> > Ok thanks guys, that provides some confidence. That other thread > >> >>> > also > >> >>> > mentioned having an invisible Om component do the listening. Not > >> >>> > sure > >> >>> > I understand the point of that; why not just add the go block to > >> >>> > anything already in the IWillMount of your root Om component? If > you > >> >>> > were to make it invisible, just put an empty om/div on there with > no > >> >>> > contents? (since a component must be returned) > >> >>> > > >> >>> > On Sun, Jun 22, 2014 at 9:24 PM, Gary Trakhman > >> >>> > <[email protected]> wrote: > >> >>> >> Let's also not forget that JS is single-threaded. I'm guessing > all > >> >>> >> the > >> >>> >> components will be recursively mounted before the contents of the > >> >>> >> go > >> >>> >> block > >> >>> >> can do anything at all. > >> >>> >> > >> >>> >> > >> >>> >> On Sun, Jun 22, 2014 at 9:20 AM, Dave Della Costa > >> >>> >> <[email protected]> > >> >>> >> wrote: > >> >>> >>> > >> >>> >>> Hi Andrew, > >> >>> >>> > >> >>> >>> We ended up doing exactly the sort of thing you describe. We > have > >> >>> >>> a > >> >>> >>> go > >> >>> >>> block inside IWillMount, listening for messages from the server > >> >>> >>> (in > >> >>> >>> our > >> >>> >>> case via browserchannel, but exact same idea). Inside this go > >> >>> >>> block > >> >>> >>> we > >> >>> >>> apply updates from our server by calling transact! on the app > >> >>> >>> data. > >> >>> >>> > >> >>> >>>> Since the block is asynchronous, couldn't the Om protocol > >> >>> >>>> (whichever > >> >>> >>>> one is best) return before the go block actually does anything? > >> >>> >>>> Or > >> >>> >>>> what happens when the go block does something at a different > time > >> >>> >>>> than the Om protocol is getting called? > >> >>> >>> > >> >>> >>> componentWillMount (a.k.a. IWillMount in Om) is called once at > the > >> >>> >>> very > >> >>> >>> beginning of the React lifecycle > >> >>> >>> > >> >>> >>> > >> >>> >>> > >> >>> >>> ( > http://facebook.github.io/react/docs/component-specs.html#mounting-componentwillmount > ), > >> >>> >>> so it's not going to cause the kind of strange behavior you're > >> >>> >>> concerned > >> >>> >>> about. If a message comes in and transact! gets called, an > update > >> >>> >>> will > >> >>> >>> be scheduled and rendering will happening as expected. > >> >>> >>> > >> >>> >>> DD > >> >>> >>> > >> >>> >>> (2014/06/22 21:24), Andrew Stoeckley wrote: > >> >>> >>>> I was reading this thread: > >> >>> >>>> > >> >>> >>>> > >> >>> >>>> > >> >>> >>>> > https://groups.google.com/forum/#!msg/clojurescript/V5J1Rf0k84M/JgspX_AyoGgJ > >> >>> >>>> > >> >>> >>>> It was suggested that all state changes to the Om atom should > >> >>> >>>> occur > >> >>> >>>> within an Om component. Currently I am swap!ing outside Om. > >> >>> >>>> > >> >>> >>>> A lot of my state changes are the result of an infinite <! loop > >> >>> >>>> inside a go block, which is reading a websocket. What happens > if > >> >>> >>>> I > >> >>> >>>> put this inside an Om component, and where is the best place to > >> >>> >>>> do > >> >>> >>>> so? IWillMount? > >> >>> >>>> > >> >>> >>>> Since the block is asynchronous, couldn't the Om protocol > >> >>> >>>> (whichever > >> >>> >>>> one is best) return before the go block actually does anything? > >> >>> >>>> Or > >> >>> >>>> what happens when the go block does something at a different > time > >> >>> >>>> than the Om protocol is getting called? > >> >>> >>>> > >> >>> >>>> Or perhaps more likely there is a better way. Any suggestions > on > >> >>> >>>> good > >> >>> >>>> approach here are appreciated. > >> >>> >>>> > >> >>> >>> > >> >>> >>> -- > >> >>> >>> Note that posts from new members are moderated - please be > patient > >> >>> >>> with > >> >>> >>> your first post. > >> >>> >>> --- > >> >>> >>> You received this message because you are subscribed to the > Google > >> >>> >>> Groups > >> >>> >>> "ClojureScript" group. > >> >>> >>> To unsubscribe from this group and stop receiving emails from > it, > >> >>> >>> send an > >> >>> >>> email to [email protected]. > >> >>> >>> > >> >>> >>> To post to this group, send email to > >> >>> >>> [email protected]. > >> >>> >>> Visit this group at > http://groups.google.com/group/clojurescript. > >> >>> >> > >> >>> >> > >> >>> >> -- > >> >>> >> Note that posts from new members are moderated - please be > patient > >> >>> >> with your > >> >>> >> first post. > >> >>> >> --- > >> >>> >> You received this message because you are subscribed to a topic > in > >> >>> >> the > >> >>> >> Google Groups "ClojureScript" group. > >> >>> >> To unsubscribe from this topic, visit > >> >>> >> > >> >>> >> > >> >>> >> > https://groups.google.com/d/topic/clojurescript/DHJvcGey8Sc/unsubscribe. > >> >>> >> To unsubscribe from this group and all its topics, send an email > to > >> >>> >> [email protected]. > >> >>> >> To post to this group, send email to > >> >>> >> [email protected]. > >> >>> >> Visit this group at http://groups.google.com/group/clojurescript > . > >> >>> > > >> >>> > >> >>> -- > >> >>> Note that posts from new members are moderated - please be patient > >> >>> with > >> >>> your first post. > >> >>> --- > >> >>> You received this message because you are subscribed to the Google > >> >>> Groups > >> >>> "ClojureScript" group. > >> >>> To unsubscribe from this group and stop receiving emails from it, > send > >> >>> an > >> >>> email to [email protected]. > >> >>> To post to this group, send email to [email protected] > . > >> >>> Visit this group at http://groups.google.com/group/clojurescript. > >> >> > >> >> > >> > > >> > -- > >> > Note that posts from new members are moderated - please be patient > with > >> > your > >> > first post. > >> > --- > >> > You received this message because you are subscribed to a topic in the > >> > Google Groups "ClojureScript" group. > >> > To unsubscribe from this topic, visit > >> > > https://groups.google.com/d/topic/clojurescript/DHJvcGey8Sc/unsubscribe. > >> > To unsubscribe from this group and all its topics, send an email to > >> > [email protected]. > >> > To post to this group, send email to [email protected]. > >> > Visit this group at http://groups.google.com/group/clojurescript. > >> > >> -- > >> Note that posts from new members are moderated - please be patient with > >> your first post. > >> --- > >> You received this message because you are subscribed to the Google > Groups > >> "ClojureScript" group. > >> To unsubscribe from this group and stop receiving emails from it, send > an > >> email to [email protected]. > >> To post to this group, send email to [email protected]. > >> Visit this group at http://groups.google.com/group/clojurescript. > > > > > > -- > > Note that posts from new members are moderated - please be patient with > your > > first post. > > --- > > You received this message because you are subscribed to a topic in the > > Google Groups "ClojureScript" group. > > To unsubscribe from this topic, visit > > https://groups.google.com/d/topic/clojurescript/DHJvcGey8Sc/unsubscribe. > > To unsubscribe from this group and all its topics, send an email to > > [email protected]. > > To post to this group, send email to [email protected]. > > Visit this group at http://groups.google.com/group/clojurescript. > > -- > Note that posts from new members are moderated - please be patient with > your first post. > --- > You received this message because you are subscribed to the Google Groups > "ClojureScript" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/clojurescript. > -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/clojurescript.
