Could you describe your mixin a bit more? We’ve just written an om component 
and macro to help clean up go-blocks in cases like these. Several of our 
components take channels as input from parent components to allow for more 
sophisticated communication. We’ll post a link to this manager component today 
or tomorrow after we add some documentation.

Regarding the second problem, we don’t typically do that either. I was just 
being lazy when writing the error demo and ran into. Curious behaviour, but 
easy to avoid the problem.


From: Daniel Kersten <dkers...@gmail.com>
Reply: clojure@googlegroups.com <clojure@googlegroups.com>>
Date: July 25, 2014 at 5:26:56 AM
To: clojure@googlegroups.com <clojure@googlegroups.com>>
Subject:  Re: subtle om + core.async problems  

You could simplify your fix code a small bit by using go-loop and when, like 
this:

(go-loop []
  (let [[v ch] (alts! [dump-chan (om/get-state owner :exit-chan)])]
    (when (= ch dump-chan)
      (.log js/console "dumping state:")
      (.log js/console (pr-str (om/get-state owner)))
      (recur))))

This won't work in your code because my-form's parent owns dump-chan, but if a 
component owns the channel, an alternative approach is to simply close 
dump-chan in IWillUnmount and change your go block to something like this:

(go-loop []
  (when-let [v (<! dump-chan)]
    (.log js/console "dumping state:")
    (.log js/console (pr-str (om/get-state owner)))
    (recur)))

In my own code, I've abstracted my go blocks into om-tools mixins that handle 
the killing of go blocks.

I'm not sure why the second problem happens. As a general rule, I never create 
new resources in render (IMO render should be pure functional: app state and 
local state in -> new dom nodes out; but as the child stores the channel 
between calls to parents render, this breaks that "rule") and I've never had 
the issue.
Since base isn't being re-rendered in this case, I'm not sure why this would be 
a problem here.



On 24 July 2014 02:35, Sean Corfield <s...@corfield.org> wrote:
You'll want to read this thread: 
https://groups.google.com/forum/#!topic/clojurescript/DHJvcGey8Sc

In particular:

"So if you have code that's like this, those components will want to clean up 
after themselves in IWillUnmount."

That should address your first problem?

I'm not sure what to suggest right now about the second problem.

Sean


On Jul 23, 2014, at 4:19 PM, Alexander Hudek <alexan...@hudek.org> wrote:
I've encountered two subtle but serious problems using om with core.async.

The first one is illustrated by this code: 

https://github.com/akhudek/om-async-error

First, one obvious solution here is to move the dump-chan inside the form 
state. 
However, it's written this way to illustrate the error which originally arose 
in a 
dialog component that took both an action channel that receives button presses
and a dialog content component. It exposed the action channel in this way in 
order to be flexible. 

I believe the cause of this error is that when you toggle the form in the demo 
to off, it unmounts the component. However, the go-block is still active and
listening to the channel. When you toggle the form back on, a new component
is created and mounted. Now you have two components listening on the same
channel!

The ideal solution might be to find a way to end the go block when the component
unmounts. This is easy to do on a case by case basis, but not easy to do in a
completely generic fashion. Here is one solution:

https://github.com/akhudek/om-async-error/blob/alts-fix/src/om_async_error/core.cljs

The second problem is easy to fix, however, I don't understand why it happens.

https://github.com/akhudek/om-async-error/tree/chan-opts-bug

Instead of initializing the dump channel in the base components state, we 
initialize
it when creating the form component. As soon as you start typing into the form
the channel breaks. It was suggested on irc that this might be because of a 
re-render of base would create a new channel, but the form component will not
be re-mounted because it's already mounted. However, putting in some debug
code shows that there is no re-render of the base component occurring between
when the channel works and when it doesn't. 

I'm posting this here mostly to warn people to be wary of these situations. Of
course, if you have any suggestions or explanations for these I'd love to hear 
them.

Alex



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google 
Groups "Clojure" group.
To unsubscribe from this topic, visit 
https://groups.google.com/d/topic/clojure/abczlIGvogk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to 
clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to