core.async

How do I unit test clojure.core.async go macros?

a 夏天 提交于 2021-02-06 15:24:30
问题 I'm trying to write unit tests when using core.async go macros. Writing the test naively, as follows, appears that the code inside the go blocks doesn't get executed. (ns app.core-test (:require [clojure.test :refer :all] [clojure.core.async :as async])) (deftest test1 [] (let [chan (async/chan)] (async/go (is (= (async/<! chan) "Hello"))) (async/go (async/>! chan "Hello")))) I've managed to get the following working, but it's extremely hacky. (deftest test1 [] (let [result (async/chan) chan

How do I unit test clojure.core.async go macros?

点点圈 提交于 2021-02-06 15:20:49
问题 I'm trying to write unit tests when using core.async go macros. Writing the test naively, as follows, appears that the code inside the go blocks doesn't get executed. (ns app.core-test (:require [clojure.test :refer :all] [clojure.core.async :as async])) (deftest test1 [] (let [chan (async/chan)] (async/go (is (= (async/<! chan) "Hello"))) (async/go (async/>! chan "Hello")))) I've managed to get the following working, but it's extremely hacky. (deftest test1 [] (let [result (async/chan) chan

How do clojure core.async channels get cleaned up?

前提是你 提交于 2020-01-31 09:06:14
问题 I'm looking at Clojure core.async for the first time, and was going through this excellent presentation by Rich Hickey: http://www.infoq.com/presentations/clojure-core-async I had a question about the example he shows at the end of his presentation: According to Rich, this example basically tries to get a web, video, and image result for a specific query. It tries two different sources in parallel for each of those results, and just pulls out the fastest result for each. And the entire

Why do core.async go blocks return a channel?

允我心安 提交于 2019-12-24 01:01:40
问题 I understand that 'go blocks' (whether go or go-loop or possibly other constructs) return a channel. However I have never understood this channel's purpose. I'd like to know how to use it. Perhaps I'm creating extra channels when I don't need to be. 回答1: I use the return channel of a go -block as a handle that I can pass to another function (not just a macro) which wants to synchronize with the completion of the go -block. Alternatively, I can preform blocking reads on the channel to

How do you write to a log file in Clojure, using core.async?

◇◆丶佛笑我妖孽 提交于 2019-12-24 00:40:08
问题 I want to use core.async as a logger that writes out to a file, so I created a test.txt file, stuck it in my resources folder and wrote this code: (use 'clojure.java.io) (use 'clojure.core.async) (def print-chan (chan)) (go (loop [] (when-let [v (<! print-chan)] (with-open [wrtr (writer "resources/test.txt" :append true)] (.write wrtr v)) (recur)))) (>!! print-chan 42) When I run this, however, I find that it will only replace what is in the file, and not append to it. Also, sometimes the

How to memoize a function that uses core.async and non-blocking channel read?

百般思念 提交于 2019-12-22 08:57:36
问题 I'd like to use memoize for a function that uses core.async and <! e.g (defn foo [x] (go (<! (timeout 2000)) (* 2 x))) (In the real-life, it could be useful in order to cache the results of server calls) I was able to achieve that by writing a core.async version of memoize (almost the same code as memoize): (defn memoize-async [f] (let [mem (atom {})] (fn [& args] (go (if-let [e (find @mem args)] (val e) (let [ret (<! (apply f args))]; this line differs from memoize [ret (apply f args)] (swap

Clojure core.async, CPU hangs after timeout. Anyway to properly kill macro thread produced by (go..) block?

时间秒杀一切 提交于 2019-12-22 04:53:38
问题 Based on core.async walk through example, I created below similar code to handle some CPU intensive jobs using multiple channels with a timeout of 10 seconds. However after the main thread returns, the CPU usage remains around 700% (8 CPUs machine). I have to manually run nrepl-close in emacs to shut down the Java process. Is there any proper way to kill macro thread produced by (go..) block ? I tried close! each chan, but it doesn't work. I want to make sure CPU usage back to 0 by Java

Clojure - Why does execution hang when doing blocking insert into channel? (core.async)

邮差的信 提交于 2019-12-18 21:26:05
问题 Consider the following snippet: (let [chs (repeatedly 10 chan)] (doseq [c chs] (>!! c "hello")) (doseq [c chs] (println (<!! c)))) Executing this will hang forever. Why is that? If I do (go (>! c "hello")) instead, it works just fine. 回答1: To make an asynchronous put, use clojure.core.async/put! (let [chs (repeatedly 10 chan)] (doseq [c chs] (put! c "hello")) (doseq [c chs] (println (<!! c)))) This works in this example as <!! will always unblock because of all necessary puts happening

What are the tradeoffs of the ways to do work in a clojure core.async go-loop?

蹲街弑〆低调 提交于 2019-12-12 08:55:20
问题 As I write more core.async code, a very common pattern that emerges is a go-loop that alts over a sequence of channels and does some work in response to a message, e.g.: (go-loop [state {}] (let [[value task] (alts! tasks)] ...work... (recur state)) I don't feel like I understand the tradeoffs of the various ways I can actually do the work though, so I thought I'd try to explore them here. Inline or by calling a function: this blocks the loop from continuing until the work is complete. Since

Server push of data from Clojure to ClojureScript

南楼画角 提交于 2019-12-12 07:29:58
问题 I'm writing an application server in Clojure that will use ClojureScript on the client. I'd like to find an efficient, idiomatic way to push data from the server to the client as realtime events, ideally using a some combination of: http-kit core.async Ring (But I'm open to other possibilities) Can anyone provide a good example / approach to doing this? 回答1: I prefer to use aleph, here is the wiki, you can simply use wrap-ring-handler function to wrap existed handlers. For the 'push' function