Clojure实现带超时的期货向量
Clojure realize vector of futures with timeout
我正在连接一个 Java API 那个 returns 一个 CompletableFuture
。
现在,如果我有这些 [cf1 cf2 cf3 …]
的数组,我如何给它们 all 一秒完成,并在一秒后收集它们产生的任何东西?
类似于:
(def vec-of-cf [cf1 cf2 cf3])
(get-all vec-of-cf 1000 ::timeout)
;; no more than 1 second later, I should have my vector of realized CompletableFuture, possibly holding a `::timeout` value if they did not have time to finish
我认为这类似于 Scala flatmap
(?).
像这样的东西应该可以工作:
(defn get-all [vec-of-cf timeout timeout-val]
(Thread/sleep timeout)
(mapv #(if (future-done? %) (deref %) timeout-val) vec-of-cf))
也可以修改此代码以取消未完成的未来(如果需要)
您可以使用 CompletableFuture.allOf
来获得一个可完成的未来,您可以阻塞等待所有任务完成或超时所需的时间(因此等待时间可能短于超时时间 - 所有任务都已完成到一秒,不一定在一秒之后),然后迭代原始期货以获得它们的价值(如果完成):
(def vec-of-cf [cf1 cf2 cf3])
(let [all-of (CompletableFuture/allOf (into-array vec-of-cf))]
(try
(.get all-of timeout)
(catch java.util.concurrent.TimeoutException e))
(->> vec-of-cf
(filter #(.isDone %))
(map #(.get %))))
我正在连接一个 Java API 那个 returns 一个 CompletableFuture
。
现在,如果我有这些 [cf1 cf2 cf3 …]
的数组,我如何给它们 all 一秒完成,并在一秒后收集它们产生的任何东西?
类似于:
(def vec-of-cf [cf1 cf2 cf3])
(get-all vec-of-cf 1000 ::timeout)
;; no more than 1 second later, I should have my vector of realized CompletableFuture, possibly holding a `::timeout` value if they did not have time to finish
我认为这类似于 Scala flatmap
(?).
像这样的东西应该可以工作:
(defn get-all [vec-of-cf timeout timeout-val]
(Thread/sleep timeout)
(mapv #(if (future-done? %) (deref %) timeout-val) vec-of-cf))
也可以修改此代码以取消未完成的未来(如果需要)
您可以使用 CompletableFuture.allOf
来获得一个可完成的未来,您可以阻塞等待所有任务完成或超时所需的时间(因此等待时间可能短于超时时间 - 所有任务都已完成到一秒,不一定在一秒之后),然后迭代原始期货以获得它们的价值(如果完成):
(def vec-of-cf [cf1 cf2 cf3])
(let [all-of (CompletableFuture/allOf (into-array vec-of-cf))]
(try
(.get all-of timeout)
(catch java.util.concurrent.TimeoutException e))
(->> vec-of-cf
(filter #(.isDone %))
(map #(.get %))))