Skip to content

Instantly share code, notes, and snippets.

@oubiwann
Created October 30, 2012 00:03
Show Gist options
  • Save oubiwann/3977479 to your computer and use it in GitHub Desktop.
Save oubiwann/3977479 to your computer and use it in GitHub Desktop.
Agents in Clojure, Part II
(def read-agent (agent "" :validator string?))
(defn read-agent-error-handler [agnt, exception]
(println "Whoops! " agnt " had a problem: " exception))
(def read-agent (agent "" :error-handler read-agent-error-handler))
(set-validator! read-agent string?)
(set-error-handler! read-agent read-agent-error-handler)
(defn read-watch [key agnt old-value new-value]
(println "File has been read!")
(println (str "Watch key: " key))
(println (str "Agent: " agnt))
(println (str "Agent's old value: " old-value))
(println (str "Agent's new value: " new-value)))
(add-watch read-agent "reader-01" read-watch)
(defn read-agent-error-handler [agnt, exception]
(println "Whoops! " agnt " had a problem: " exception))
(def read-agent
(agent
"zero bytes"
:validator string?
:error-handler read-agent-error-handler))
(defn big-read [old-value seconds]
"Pretent to read a really big file"
(time (Thread/sleep (* seconds 1000)))
"<contents of big file>")
(defn read-watch [key agnt old-value new-value]
(println "File has been read!")
(println (str "New file data is: " new-value))
(println ""))
(add-watch read-agent "reader-01" read-watch)
$ start-clojure
Clojure 1.4.0
user=> (ns async-2)
nil
async-2=> (load-file "05-agent.clj")
#<Agent@2598c6f3: "zero bytes">
async-2=>
async-2=> (send-off read-agent big-read 20)
#<Agent@2598c6f3: "zero bytes">
async-2=>
async-2=> ; let's do something else while we're waiting
async-2=> ; maybe some simple math?
async-2=> (+ 1 1)
2
async-2=>
async-2=> "Elapsed time: 10000.776 msecs"
File has been read!
New file data is: <contents of big file>
(defn relay [x i]
(when (:next x)
(send (:next x) relay i))
(when (and (zero? i) (:report-queue x))
(.put (:report-queue x) i))
x)
(defn run [action-count agent-count]
(let [q (new java.util.concurrent.SynchronousQueue)
hd (reduce (fn [next _] (agent {:next next}))
(agent {:report-queue q})
(range (dec action-count)))]
(doseq [i (reverse (range agent-count))]
(send hd relay i))
(.take q)))
async-2=> (time (run 1000 1000))
"Elapsed time: 1003.892 msecs"
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment