I assume that (<! subscriber-ch)will return nil when subscriber-ch is closed? I vaguely remember this to be the case, though have not tested it. If it does, then your way looks good to me.
On 31 August 2014 02:40, Dhruv Bhatia <[email protected]> wrote: > Thanks a lot. > > I managed to create a solution which doesn't require a separate > kill-channel. It seems to be side-effect free and cleans up as expected, > though I’m still quite new to Clojurescript and core.async so I may be > wrong! > > ; UTIL.CLJS > ; PUB/SUB SETUP > > ; create a global events-ch channel which is used to transport messages > (def events-ch (chan)) > > ; broadcaster allows us to subscribe to certain topics within events-ch > (def broadcaster > (pub events-ch #(:topic %))) > > ; MY-COMPONENT.CLJS > > ; my-component wants to subscribe to the :login-error topic in our global > events-ch channel > (defn my-component [app owner] > (reify > om/IInitState > (init-state [_] > {:subscriber-ch nil}) > om/IDidMount > (did-mount [_] > (let [broadcaster util/broadcaster > subscriber-ch (chan)] > (do > (om/set-state! owner :subscriber-ch subscriber-ch) > (sub broadcaster :login-error subscriber-ch) > (go-loop [] > (when-let [message (:message (<! > subscriber-ch))] > (do-something message) > (recur)))))) > om/IWillUnmount > (will-unmount [_] > (let [broadcaster util/broadcaster > subscriber-ch (om/get-state owner :subscriber-ch)] > (do > (js/console.log "unsubing/closing channel" > subscriber-ch) > (unsub broadcaster :login-error subscriber-ch) > (close! subscriber)))) > om/IRenderState > (render-state [this state] > ... > > > > On Aug 31, 2014, at 11:23 AM, Daniel Kersten <[email protected]> wrote: > > Something like this: > > (defn component [data owner] > (reify > om/IInitState > (init-state [_] > (let [chan (chan)] > {:chan chan > :kill (chan) > :pub (pub chan first)})) > > om/IWillMount > (will-mount [_] > (let [pub (om/get-state owner :pub) > chan (chan) > kill (om/get-state owner :kill)] > ; If using pub/sub, need to subscribe > *(sub pub :foo chan) * > (go-loop [] > (let [*[v c]* *(alts! [chan kill])*] > (when-not *(= c kill)* > (do-something v) > (recur)) > ; If using pub/sub, need to unsubscribe: > *(unsub pub :foo chan)*)))) > > om/IWillUnmount > (will-unmount [_] > *(put! (om/get-state owner :kill) :quit)*) > > om/IRenderState > (render-state [_ {:keys [chan]}] > (dom/div {:onClick #(put! chan [:foo "Hello"])} > "Click me to send [:foo \"Hello\"]")))) > > > > On 30 August 2014 16:08, Dhruv Bhatia <[email protected]> wrote: > >> On Sunday, 13 July 2014 01:46:41 UTC+10, Daniel Kersten wrote: >> > Channels are cheap, but unless they get garbage collected (and I assume >> not closing them will prevent this), they will still take up some resources. >> > >> > >> > Related and important is that you shut down any go blocks that you >> create in IWillMount, especially if they take from a channel which may >> still be receiving data (eg: through mux or pub/sub). If you don't shut >> these down, they will continue to run even after the component has >> unmounted and if the component is later mounted again, you will have >> multiple go blocks doing the same thing! Besides using resources, this can >> actually be dangerous if you are accessing owner inside the go block (eg to >> set local state) as you may end up accessing an unmounted owner. The >> simplest solution is having a kill channel that you listen on using >> async/alt that gets closed in the IWillUnmount and that terminates the go >> block. >> >> Thanks for the explanation. Would you be able to provide a code example >> that demonstrates how to properly clean up a pub/sub watcher within a >> component's IWillUnmount lifecycle method? >> >> -- >> 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/_a5dPeElqG4/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.
