如何在 Clojure 中执行同步并行函数?

How to perform synchronous parallel functions in Clojure?

我的应用程序有一个可以并行完成的初始流程:

  1. 获取两个 JSON 文档(我为此使用 clj-http
  2. 解析这些文档(只提取需要的数据)
  3. 加入结果
  4. 将它们转储到一个文件中

所以有这样的东西:

some-entry-point
      /\
     /  \
    /    \
   /      \
fetchA   fetchB
  |         |
  |         |
parseA   parseB
  \        /
   \      /
    \    /
     \  /
      \/
     join
      |
      |
     dump

实现该目标的正确且最新的方法是什么?

目前我发现的是:

因为你在这里有两个分支,最好使用 future function. future 将并行作业分派到单独的线程 return 你将成为未来的对象(一个特殊的承诺,将自动解决作业何时完成)。

外观如下:

(defn some-entry-point
  [obja objb]
  (let [pa (-> (fetchA obja)
               parseA
               future)
        pb (-> (fetchB objb)
               parseB
               future)]
    (-> (join @pa @pb)
        dump)))

@ 这里是 deref 函数的快捷方式(reader 宏)。

当然,您可以在主线程中执行其中一个分支,只创建一个未来对象:

(defn some-entry-point
  [obja objb]
  (let [p (-> (fetchB objb)
              parseB
              future)]
    (-> (fetchA obja)
        parseA
        (join @p)
        dump)))

您还可以使用一些通用的 fetchparse 函数概括这种方法来获取和解析多个对象,使用 pmap 进行并行化:

(defn some-entry-point
  "Fetch and parse multiple objects in parallel"
  [objs]
  (->>  objs
        (pmap (comp parse fetch))
        (apply join)
        dump))