Fork me on GitHub

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 -

Alex Miller (Clojure team)19:02:36

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


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


Avoiding any potential pending/new writes while draining


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


Or add a close! inside drain! ?


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


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


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


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.


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


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?


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


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


alts is pretty damn cool


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


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


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


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


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


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


core async makes some higher-level coordination patterns easier


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


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?