Reputation: 2893
I have a Clojure code which runs a few threads in parallel. They all share an atom: (def counter (atom 0))
which is incremented by each thread. Every 10 minute, I'd like to perform several actions using the value of the atom and then reset it back to 0 - for example:
(defn publish-val []
(let [c @counter]
(email c)
(statsd c)
(print-log c)
(reset! counter 0)))
It is important that the value of counter
will not change from the moment it is dereferenced to the moment it is reset - meaning all threads should be blocked when trying to change the atom's value while publish-val
is executed. How do I do this?
Upvotes: 1
Views: 381
Reputation: 33029
Unless you've greatly simplified the problem for your example, it looks like swap!
-ing out the current counter value with zero would be sufficient here:
(defn publish-val []
(with-local-vars [c nil]
(swap! counter
(fn [x] (var-set c x) 0))
(email @c)
(statsd @c)
(print-log @c)))
So you just save your old counter value in a local variable, atomically swap it with zero, and then do whatever bookkeeping needed to do with the old value—all without stalling any of the other threads longer than it takes to swap!
Upvotes: 4
Reputation: 69
Use an agent.
See the section Using agents to serialise access to non-threadsafe resources about using them to print to console
Upvotes: 2