Fork me on GitHub
#core-async
<
2016-02-11
>
hugesandwich19:02:49

Is there a preferred way right now to drain a channel? (Take all values and then close)? I can think of a few ways, but I'm not looking to reinvent the wheel. I see there is still an open issue - http://dev.clojure.org/jira/browse/ASYNC-66?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

Alex Miller (Clojure team)19:02:36

my expectation is that we will eventually add something like ASYNC-66

hugesandwich19:02:02

Thanks, I figured. So any guidance what the preferred way is in the meantime to be sure all the values are drained?

hugesandwich19:02:53

Avoiding any potential pending/new writes while draining

danielcompton21:02:10

@hugesandwich: close the channel before calling drain on it?

danielcompton21:02:20

Or add a close! inside drain! ?

hugesandwich21:02:11

Yes, that works but I just added that bit about the general approach, not how to do it

hugesandwich21:02:52

The real issue is what should be the behavior with any pending puts and takes, and ensuring the channel is drained immediately if possible

hugesandwich21:02:23

So like I said, lots of ways to do this, the question is if the community has a preferred way that is safe and battle-tested

Alex Miller (Clojure team)21:02:39

not to my knowledge, but comments on that ticket (or patches) would be ideal

hugesandwich21:02:22

OK, I'll see what I can add when I get a chance. Trying to avoid this for now as I fear somewhere there's going to be an issue. I'm trying to drain a channel for the purposes of avoiding data loss and maintaining order when preforming a circuit-breaker like operation/switch.

alexisgallagher22:02:52

Is there any fundamental difference between (doseq [i coll] (async/>! mychan i)) and (async/onto-chan mychan coll false)?

rickmoynihan22:02:07

Hey - I've been meaning to ask this for a while.... Basically every now and then I have to write some clojure code that communicates across a thread; e.g. sometimes with ring you need to spawn a thread and have it marshal results asynchronously into an inputstream on the HTTP response body... Anyway, I've historically always just reached for one of the j,u.c.Queue's and used that to marshal results etc across threads. What would be the benefit of using core.async to do this stuff and why should I prefer it to things in j.u.c?

rickmoynihan22:02:16

I appreciate that it's more functional - and transducers might mean I could abstract across seqs/chans etc

ghadi22:02:45

ring specifically doesn't handle multithreading -- but the advantages of a channel are that the alts operation enables select / cancellation, j.u.c doesn't do that at all

rickmoynihan22:02:08

alts is pretty damn cool

ghadi22:02:16

having non-trivial coordination can be handled with a go block

rickmoynihan22:02:03

what I don't fully grok is the interaction between coroutine pseudo threads and real JVM threads

rickmoynihan22:02:25

I'm mostly using threads for I/O - so guessing real threads might be better

ghadi22:02:40

another thing is that j.u.c. queues need real threads consuming

ghadi22:02:53

you may be fine with j.u.c., depends on the usecase

rickmoynihan22:02:34

@ghadi: the j.u.c code I've written has always proven robust - like some of it has been unchanged in production for years

ghadi22:02:22

core async makes some higher-level coordination patterns easier

rickmoynihan22:02:10

so I clearly wouldn't need to do that - but would pick up an extra dependency

alexisgallagher23:02:02

It seems like a common pattern is to write a go-loop that polls a source in order to supply a chan eagerly, and to write a go-loop that polls a possible sink in order to drain a chan eagerly. Are there generic helper functions for this?