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 derefed, 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