Skip to content

Instantly share code, notes, and snippets.

@michalmarczyk
Created July 14, 2013 01:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michalmarczyk/5992795 to your computer and use it in GitHub Desktop.
Save michalmarczyk/5992795 to your computer and use it in GitHub Desktop.
Short-circuiting logical disjunction of several futures' results
(defn thread-or
"Call each of the fs on a separate thread. Return logical
disjunction of the results. Short-circuit (and cancel the calls to
remaining fs) on first truthy value returned."
[& fs]
(let [ret (promise)
fps (promise)]
(deliver fps
(doall (for [f fs]
(let [p (promise)]
[(future
(let [v (f)]
(locking fps
(deliver p true)
(if v
(deliver ret v)
(when (every? realized? (map peek @fps))
(deliver ret nil))))))
p]))))
(let [result @ret]
(doseq [[fut] @fps]
(future-cancel fut))
result)))
(comment
;; prints :foo, but not :bar
(thread-or #(do (Thread/sleep 1000) (println :foo) true)
#(do (Thread/sleep 3000) (println :bar)))
;;= true
;; prints :foo and :bar
(thread-or #(do (Thread/sleep 1000) (println :foo))
#(do (Thread/sleep 3000) (println :bar)))
;;= nil
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment