Composable Async Tasks for Clojure
Fetching latest commit…
Cannot retrieve the latest commit at this time
# die-geister Die Geister is a library that provides composable tasks that execute asynchonously. ## Usage task: a macro which results in an async task. geister.core> (task (+ 1 2)) geister.core.Task@aa754f7a geister.core> @*1 3 geister.core> async: similar to let, but each value in a binding is expected to yield an async task, and async wraps its body in an implicit (task ...) geister.core> (async [x (task (+ 1 2))] (+ x 4)) geister.core.Task@90b56cdf geister.core> @*1 7 geister.core> async-loop: like clojure's built in loop. use async-recur instead of recur. each loop iteration is queued up as a seperate async task. geister.core> (async-loop [[x & xs] (range 10) t 0] (if x (async-recur xs (+ x t)) t)) geister.core.Task@90ce3f54 geister.core> @*1 45 geister.core> async tasks are chainable: geister.core> (chain (task (+ 1 2)) (fn [x] (task (inc x)))) geister.core.Task@aadbba2f geister.core> @*1 4 geister.core> async tasks are joinable: geister.core> (join (task (+ 1 2)) (task (+ 3 4))) geister.core.MultiTask@df4ec6c0 geister.core> @*1 (3 7) geister.core> exceptions are propagated through chains of async tasks. if you deref an async task and any async tasks that it depended on threw an exception, then that exception will be thrown. geister.core> (async [x (task "foo") y (task (+ 1 2))] (+ y x)) geister.core.Task@463b2d3c geister.core> (try @*1 (catch Exception e (println e))) #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> nil geister.core> by default tasks are queued on clojure's pooledExecutor (same as send). you can rebind *task-handler* to change how and where async tasks are executed. the TaskProtocol has been extended to futures so you can compose futures with async tasks geister.core> (join (future :foo) (task (+ 2 3))) geister.core.MultiTask@630cdaf geister.core> @*1 (:foo 5) geister.core> ## Installation FIXME: write ## Future remove Task record, just use Future namespace for doing async IO with tasks nicer way to schedule tasks to run, perhaps at the namespace level "all tasks in this namespace are run using function X" ## License Copyright (C) 2010 FIXME Distributed under the Eclipse Public License, the same as Clojure.