Liking cljdoc? Tell your friends :D

auspex

Auspex is small wrapper over java-11+ CompletableFuture that mimics most of manifold deferred API, including chain, catch, finally, loop/recur, zip, let-flow and most of the nice stuff.

future here represents the result of an asynchronous computation (promise), so more in the java sense than clojure.core/future (which will always run it's computation on an unbounded threadpool).

You can also use a qbits.auspex/future as replacement of clojure.core/future via (a/future (fn [] ::foo) executor) it would then realize the future on whatever ExecutorService you'd choose (there's some sugar for that on qbits.auspex.executor).

Composition functions (then, fmap, complete!, handle, finally) all have an extra/optional executor argument that allows to control where computation happens, otherwise they will use the execution context of the previous step. So if you specify an executor at a level be aware that subsequent levels will re-use it unless you specify otherwise.

Docs

cljdoc badge

Usage

Some examples

(require '[qbits.auspex :as a])

(let [f (a/future)]
  (a/success! f ::foo) -> true
  @f
  ;; returns ::foo
  )

(let [f (a/future)]
  (a/error! f (ex-info "Oh no" {})) -> true
  @f
  ;; returns ExceptionInfo Oh no
 )


(let [f (a/future)]
  (a/handle f (fn [x err]
                (prn x err)))
  (a/success! f ::foo)

  ;; prints nil ::foo
  )


(let [f (-> (a/future (fn [] 0))
            (a/then inc)
            (a/then inc))]

  @f
  ;; returns 2
  )

(let [f (-> (a/future (fn [] 0))
            (a/then inc clojure.lang.Agent/soloExecutor)
            (a/then inc clojure.lang.Agent/pooledExecutor))]

  @f
  ;; similar as before but with steps running on different executors
  )

(let [f0 (a/future)
      f (a/chain f0
                 inc
                 inc
                 inc)]

  ;; chain returns a separate future, feeding f0 will set f0 to 0, f
  ;; will be the future with the composition result
  (a/success! f0 0)
  @f
  ;; returns 3

  @f0
  ;; returns 0
  )

(let [f0 (a/future)
      f (-> (a/chain f0
                  inc
                  (fn [x] (throw (ex-info "Oh no" {})))
                  inc)
            (a/catch (fn [_] "no big deal")))]

  (a/success! f0 0)
  @f
  ;; prints no big deal
  )

(let [f0 (a/future)
      f (-> (a/chain f0
                  inc
                  (fn [x] (throw (ex-info "Oh no" {})))
                  inc)
            (a/catch clojure.lang.ExceptionInfo (fn [_] 10))
            (a/finally (fn [] (prn "...and done"))))]

  (a/success! f0 0)
  @f
  ;; returns 10
  ;; prints ...and done
  )


@(a/zip (a/success-future 1)
        2
        (a/success-future 3))
;; returns (1 2 3)


@(a/one (a/future)
        (a/success-future 2)
        (a/success-future 3))
;; returns 2


@(a/timeout! (a/future (fn []
                         (Thread/sleep 50)
                         ::foo)
                       clojure.lang.Agent/soloExecutor)
             10
             ::timed-out)
;; returns ::timed-out


@(a/loop [x []]
   (if (< (count x) 5)
     (a/recur (conj x (count x)))
     x))
;; returns [0 1 2 3 4]

@(a/loop [x 0]
   (a/chain x
            inc
            #(if (< % 5)
               (a/recur %)
               %)))
;; returns 5

@(a/let-flow [x (a/future (fn [] 0))
              :when (= x 0)
              y (+ x 1)
              z (a/future (fn [] (inc y)))]
  [x y z])

;; return [0 1 2]

Installation

Clojars Project

License

Copyright © 2019 Max Penet

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close