I have a web app where i want to be able to track the number of times a given function is called in a request (i.e. thread).
I know that it is possible to do in a non-thread local way with a ref, but how would I go about doing it thread locally?
There's a tool for this in useful called thread-local
. You can write, for example, (def counter (thread-local (atom 0)))
. This will create a global variable which, when deref
ed, will yield a fresh atom per thread. So you could read the current value with @@counter
, or increment it with (swap! @counter inc)
. Of course, you could also get hold of the atom itself with @counter
and just treat it like a normal atom from then on.
You can use a dynamic global var, bound to a value with binding
in combination with the special form set!
to change its value. Vars bound with binding
are thread-local. The following will increase *counter*
every time my-fn is called for any form called within a with-counter
call:
(def ^{:dynamic true} *counter*)
(defmacro with-counter [& body]
`(binding [*counter* 0]
~@body
*counter*))
(defn my-fn []
(set! *counter* (inc *counter*)))
To demonstrate, try:
(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5
For more information, see http://clojure.org/vars#set
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With