合并异步通道缓冲区

时间:2016-11-15 06:10:09

标签: asynchronous concurrency clojure

我有一个搜索到亚马逊的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)

2 个答案:

答案 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>))))