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.

Reply via email to