Re: [ClojureScript] Consequences of not closing channels in browser?

2014-11-15 Thread Jordan Arentsen
On Saturday, August 30, 2014 8:24:19 PM UTC-5, Daniel Kersten 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 dh...@dhruvbhatia.com 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 clojurescrip...@googlegroups.com.
 
 To post to this group, send email to clojur...@googlegroups.com.
 
 Visit this group at http://groups.google.com/group/clojurescript.

This was so extremely helpful, thanks!

-- 
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Consequences of not closing channels in browser?

2014-09-01 Thread Daniel Kersten
Perfect! Closing the channel is simpler than using a kill channel (in the
cases when its possible to do this - if something else owns the channel
then you can't use this method of course).


On 1 September 2014 11:41, Dhruv Bhatia dh...@dhruvbhatia.com wrote:

 Thanks for reviewing my solution Daniel. I can confirm that
 cljs.core.async.impl.channels.ManyToManyChannel.closed gets set to true after
 my component is unmounted and (! subscriber-ch)subsequently returns nil,
 so it looks to be working as expected!

 Cheers,
 Dhruv Bhatia


 On Aug 31, 2014, at 8:48 PM, Daniel Kersten dkers...@gmail.com wrote:

 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.


  --
 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 clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescript@googlegroups.com.
 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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Consequences of not closing channels in browser?

2014-09-01 Thread Dylan Butman
I use a mixin for this purpose all the time!

(defmixin go-loop-aware
  (init-aware [owner]
  {:chans {:mounted (async/chan)}})
  (will-unmount [owner]
(async/close! (om/get-state owner [:chans :mounted])))
  (go-loop-aware [owner read-chan callback]
(when (exists? js/window)
  (let [mounted (om/get-state owner [:chans :mounted])]
(go-loop []
  (when-some [v (first (async/alts! [read-chan mounted]))]
 (callback v)
 (recur)))

I like the kill channel solution better personally since like Daniel point out, 
it doesn't require the read-chan to be owned or controlled by the component. 

When [:chans :mounted] is closed, the go-loop exits. I always use when-some 
over when-let here since when-let would close the go block if false was ever 
submitted to your read channel, whereas when-some only evaluates (not= nil)

-- 
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Consequences of not closing channels in browser?

2014-08-31 Thread Daniel Kersten
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 dh...@dhruvbhatia.com 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 dkers...@gmail.com 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 dh...@dhruvbhatia.com 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 clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescript@googlegroups.com.
 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 

Re: [ClojureScript] Consequences of not closing channels in browser?

2014-08-30 Thread Dhruv Bhatia
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Consequences of not closing channels in browser?

2014-08-30 Thread Daniel Kersten
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 dh...@dhruvbhatia.com 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 clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescript@googlegroups.com.
 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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


Re: [ClojureScript] Consequences of not closing channels in browser?

2014-08-30 Thread Dhruv Bhatia
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 dkers...@gmail.com 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 dh...@dhruvbhatia.com 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 clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescript@googlegroups.com.
 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 
 clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescript@googlegroups.com.
 Visit this group at http://groups.google.com/group/clojurescript.

-- 
Note that posts from new members are 

Re: [ClojureScript] Consequences of not closing channels in browser?

2014-07-12 Thread Daniel Kersten
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.


On 12 July 2014 02:24, Roberto Oliveros robertoolive...@mac.com wrote:

 I'm using Om for the client side and through the lifetime of the
 application many components gets mounted/unmounted. When mounted, various
 channels are opened (in go blocks). And I'm planning to use IWillUnmount to
 close them too. But first, my questions are: What happens to unclosed
 channels? Do the resources they used get released? Not closing channels
 (when unmounting components) can degrade the browser performance in the
 longrun? Thanks.

 --
 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 clojurescript+unsubscr...@googlegroups.com.
 To post to this group, send email to clojurescript@googlegroups.com.
 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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.


[ClojureScript] Consequences of not closing channels in browser?

2014-07-11 Thread Roberto Oliveros
I'm using Om for the client side and through the lifetime of the application 
many components gets mounted/unmounted. When mounted, various channels are 
opened (in go blocks). And I'm planning to use IWillUnmount to close them too. 
But first, my questions are: What happens to unclosed channels? Do the 
resources they used get released? Not closing channels (when unmounting 
components) can degrade the browser performance in the longrun? Thanks.

-- 
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 clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.