我是core.async(以及更普遍的CSP)的新手,并且很难找到良好的调试策略。特别是,我经常未能诊断代码中哪部分无穷期阻止了主线程。我这里有一个特别的例子。
(deftest passing-test
(let [c (async/to-chan! [2 1 0 5 4])]
(is (= [2 1 0 5 4]
(async/<!! (async/into [] c))))))
(deftest hanging-test
(let [[e o] (->> (async/to-chan! [2 1 0 5 4])
(async/split even?))]
(is (= [2 0 4]
(async/<!! (async/into [] e))))
(is (= [1 5]
(async/<!! (async/into [] o))))))
第一个测试通过并且不会阻止主线程。第二个测试会无限期挂起。唯一的区别是添加了async/split
来将偶数和奇数整数路由到它们各自的channel。
我的具体问题是以下这些:
什么解释了第一个和第二个测试在阻止主线程方面的不同?
有哪些调试意外阻止主线程的核心.async代码的策略?
编写为创建和操作channels的代码的单元测试的最佳方式是什么?(async/<!! (async/into [] o))
是否是收集通过channel流动的值的合理方式?