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.