Skip to content

Instantly share code, notes, and snippets.

@ordnungswidrig
Created April 20, 2011 12:47
Show Gist options
  • Save ordnungswidrig/931238 to your computer and use it in GitHub Desktop.
Save ordnungswidrig/931238 to your computer and use it in GitHub Desktop.
Form logging in clojure
(ns flog)
(defprotocol Log
(append [log expression])
(replay [log]))
(deftype SeqLog [log-ref]
Log
(append [seqlog expression] (alter log-ref conj expression))
(replay [seqlog]
(doseq [entry @log-ref]
(println ">>> " entry)
(load-string entry))))
(def *inlog* nil)
(def *replay* nil)
(defmacro in-log [log & body]
(let [body-as-string (apply pr-str body)
shall-log (and (not *inlog*))]
(binding [*inlog* true]
`(do
~(when shall-log
`(when-not *replay* (append ~log ~body-as-string)))
~@body))))
(defn test1 []
(let [lr (ref [])
l (new SeqLog lr)
w (ref {})]
(dosync
(in-log l
(inc 1))
(in-log l
(alter w assoc :123 "baz"))
(in-log l
(alter w assoc :foo 1)
(alter w update-in [:foo] inc)
(in-log l
(alter w update-in [:foo] inc))
(alter w update-in [:foo] dec)))
{:lr @lr :w @w}))
(def b1 (ref nil))
(def b2 (ref nil))
(defn testBalance []
(let [sl
(let [lr (ref [])
sl (new SeqLog lr)
b1 (ref nil)
b2 (ref nil)
a (agent nil)]
(dosync
(in-log sl
(ref-set b1 0)
(ref-set b2 0)))
(dotimes [i 1000]
(send-off a
(fn [a]
(let [r (- 500 (rand-int 1000))]
(dosync
(in-log sl
(alter b1 + r)
(alter b2 - r)))))))
(await a)
(println "b1/b2" @b1 @b2)
sl)]
(dosync
(let [b1 (ref nil) b2 (ref nil)]
(replay sl)
(println "b1/b2" b1 b2))))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment