Created
July 12, 2013 21:50
-
-
Save michalmarczyk/5988137 to your computer and use it in GitHub Desktop.
Short-circuiting logical conjunction of several futures' results in core.async
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn thread-and | |
"Call each of the fs on a separate thread. Return logical | |
conjunction of the results. Short-circuit (and cancel the calls | |
to remaining fs) on first falsey value returned." | |
[& fs] | |
(let [futs-and-cs | |
(doall (for [f fs] | |
(let [c (chan)] | |
[(future (>!! c (f))) c])))] | |
(loop [futs-and-cs futs-and-cs] | |
(if (seq futs-and-cs) | |
(let [[result c] (alts!! (map peek futs-and-cs))] | |
(if result | |
(recur (remove #(identical? (peek %) c) | |
futs-and-cs)) | |
(do (doseq [fut (map first futs-and-cs)] | |
(future-cancel fut)) | |
false))) | |
true)))) | |
(comment | |
(thread-and (constantly true) (constantly true)) | |
;;= true | |
(thread-and (constantly true) (constantly false)) | |
;;= false | |
;; prints :foo before returning false | |
(thread-and #(do (Thread/sleep 3000) false) | |
#(do (Thread/sleep 1000) (println :foo))) | |
;; does not print :foo | |
(thread-and #(do (Thread/sleep 3000) false) | |
#(do (Thread/sleep 7000) (println :foo))) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Written in reponse to this SO question: with Clojure threading long running processes and comparing their returns.