简体   繁体   English

合并异步通道缓冲区

[英]Merging an async channel buffer

I have a list of ISBNs that do a search to Amazon. 我有一个搜索到亚马逊的ISBN列表。 I've already solved this sequentially so the task now is to implement concurrency. 我已经按顺序解决了这个问题,所以现在的任务就是实现并发。 I tried it out using core.async . 我用core.async试了core.async The problem I am having is after the searches are complete, I need to be able to merge all the books into a collection so that I can sort them by book rank. 我遇到的问题是在搜索完成后,我需要能够将所有书籍合并到一个集合中,以便我可以按书籍排序对它们进行排序。 Since I am using one channel with a buffer size of 10 I'm not sure how to go about doing that. 由于我使用的缓冲区大小为10的一个通道,我不知道该怎么做。 My approach may be totally wrong. 我的做法可能完全错了。 Help is appreciated. 感谢帮助。

Here is the function for concurrency 这是并发功能

(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))))])
    )
)

get title: 得到标题:

(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]]))

and the call: 和电话:

(def list_of_isbns (split_isbns "src/clj_amazon/isbn_list.txt"))
(concurrency_test list_of_isbns)

You should be able to use 你应该可以使用

(async/reduce conj '() book-chan)

to create a collection of all items in the channel, but remember to close the channel because reduce will not return a result until the channel has been closed. 创建频道中所有项目的集合,但请记住关闭频道,因为在频道关闭之前,reduce不会返回结果。

If your goal is to overlap all I/O bound tasks (eg amazon-search) and parallelize all CPU bound tasks (eg parsing the report, etc), then you should look into the pipeline functions. 如果您的目标是重叠所有I / O绑定任务(例如amazon-search)并并行化所有CPU绑定任务(例如解析报告等),那么您应该查看管道功能。 Here is some pseudo codes illustrating their usages: 这里有一些伪代码说明了它们的用法:

(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>))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM