Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@halgari
Last active January 31, 2018 12:32
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save halgari/7028120 to your computer and use it in GitHub Desktop.
Save halgari/7028120 to your computer and use it in GitHub Desktop.
Async Agents via core.async
(use 'clojure.core.async)
(defprotocol ISendable
(channel [this]))
(defn async-agent [state]
(let [c (chan Long/MAX_VALUE) ;; <<-- unbounded buffers are bad, but this matches agents
a (atom state)]
(go-loop []
(when-let [[f args] (<! c)]
(reset! a (<! (apply f @a args)))
(recur)))
(reify
ISendable
(channel [this] c)
clojure.lang.IDeref
(deref [this] @a))))
(defn send! [a f & args]
(put! (channel a) [f args]))
(def a (async-agent 0))
(defn async-add [a b]
(go (+ a b)))
(defn delayed-async-add [a delay b]
(go (<! (timeout delay))
(+ a b)))
(send! a async-add 1)
(deref a)
;;; Execute the following code several times, and then notice how the deref of a slowly increments.
(send! a delayed-async-add 1000 1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment