Created
September 17, 2013 17:22
-
-
Save aamedina/6597546 to your computer and use it in GitHub Desktop.
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
| (defmacro future | |
| [& body] | |
| `(mvc.impl.future/future-call (fn [] (cljs.core.async.macros/go ~@body)))) | |
| (defn future-call | |
| ([f] | |
| (let [p (promise) | |
| task (fn [] | |
| (try (let [val (atom {:done false :cancelled false :value p}) | |
| val-chan (chan)] | |
| (go (let [v (<! (f))] | |
| (deliver p v) | |
| (put! val-chan v) | |
| (swap! val assoc :done true))) | |
| [val val-chan]) | |
| (catch js/Error e | |
| (deliver-exception p e)))) | |
| [state state-chan] (task)] | |
| (Future. state state-chan)))) | |
| (extend-protocol INotify | |
| channels/ManyToManyChannel | |
| (-attend [this f] | |
| (let [p (promise)] | |
| (take! this #(f %)) | |
| p))) | |
| (defn deliver | |
| [promise val] | |
| (if (instance? js/Error val) | |
| (deliver-exception promise val) | |
| (if (and (not (realized? promise)) | |
| (satisfies? INotify val)) | |
| (attend val (fn [v] | |
| (try (deliver promise v) | |
| (catch js/Error e | |
| (deliver-exception promise e))))) | |
| (-deliver promise val)))) | |
| (deftype Promise [latch v ^:mutable q ^:mutable e val-chan] | |
| IDeliver | |
| (-deliver [this val] | |
| (when (and (pos? @latch) (compare-and-set! v latch val)) | |
| (swap! latch dec) | |
| (try (put! val-chan val) | |
| (catch js/Error e | |
| (deliver-exception this e))) | |
| this)) | |
| (-deliver-exception [this exception] | |
| (-deliver this exception)) | |
| ;; remaining implementations omitted | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment