我有一个搜索到亚马逊的ISBN列表。我已经按顺序解决了这个问题,所以现在的任务就是实现并发。我用core.async
试了一下。我遇到的问题是在搜索完成后,我需要能够将所有书籍合并到一个集合中,以便我可以按书籍排序对它们进行排序。由于我使用的缓冲区大小为10的一个通道,我不知道该怎么做。我的做法可能完全错了。感谢帮助。
这是并发函数
(def book_channel (chan 10))
(defn concurrency_test [list_of_isbns]
([doseq [isbn list_of_isbns]
(go(>! book_channel(get_title_and_rank_for_one_isbn(amazon_search isbn))))])
)
)
获得标题:
(defn get_title_and_rank_for_one_isbn [amazon_report]
(def book_title (get-in amazon_report [:items 0 :item-atributes :title]))
(def sales_rank(get-in amazon_report [:items 0 :SalesRank]))
(def book_isbn(get-in amazon_report [:items 0 :asin]))
(reduce into [[book_title] [book_isbn] [sales_rank]]))
和电话:
(def list_of_isbns (split_isbns "src/clj_amazon/isbn_list.txt"))
(concurrency_test list_of_isbns)
答案 0 :(得分:0)
你应该可以使用
(async/reduce conj '() book-chan)
创建频道中所有项目的集合,但请记得关闭频道,因为在频道关闭之前,reduce不会返回结果。
答案 1 :(得分:0)
如果您的目标是重叠所有I / O绑定任务(例如amazon-search)并并行化所有CPU绑定任务(例如解析报告等),那么您应该查看管道功能。这里有一些伪代码说明了它们的用法:
(let [isbn> (chan)
report> (chan)
out> (chan)]
;; pipeline-async will take isbn from isbn> channel, invoke
;; amazon-search-async and pipe the result to report> channel.
(pipeline-async 10 ;; up to 10 I/O bound requests
report>
amazon-search-asyn
isbn>)
;; pipeline will take report from report> channel and feed it
;; to the transducer (map get-title-and-rank-etc) for processing,
;; the processed report will be pushed to the out> channel.
(pipeline (.. Runtime getRuntime availableProcessors)
out>
(map get-title-and-rank-etc)
report>)
;; read isbn from file and push it to isbn> channel
(->> "isbn_list.txt"
io/reader
line-seq
(onto-chan isbn>))
;; take all report from out> channel and sort it by rank & title
(sort-by (juxt :rank :title) (<!! (async/into [] out>))))