Потоковый счетчик в Clojure - PullRequest
       27

Потоковый счетчик в Clojure

7 голосов
/ 12 сентября 2011

У меня есть веб-приложение, в котором я хочу иметь возможность отслеживать, сколько раз данная функция вызывается в запросе (т. Е. В потоке).

Я знаю, что это можно сделать не-прибегает местный путь с реф, но как мне сделать это локально?

Ответы [ 3 ]

12 голосов
/ 12 сентября 2011

Для этого есть инструмент , полезный , который называется thread-local.Вы можете написать, например, (def counter (thread-local (atom 0))).Это создаст глобальную переменную, которая, когда deref ed, даст новый атом на поток.Таким образом, вы можете прочитать текущее значение с помощью @@counter или увеличить его на (swap! @counter inc).Конечно, вы можете также взять атом с помощью @counter и с этого момента просто обращаться с ним как с обычным атомом.

7 голосов
/ 12 сентября 2011

Вы можете использовать динамический глобальный var, связанный со значением с binding в сочетании со специальной формой set!, чтобы изменить его значение.Вары, связанные с binding, являются локальными для потока.Следующее значение будет увеличиваться *counter* каждый раз, когда my-fn вызывается для любой формы, вызываемой в with-counter вызове:

(def ^{:dynamic true} *counter*)

(defmacro with-counter [& body]
  `(binding [*counter* 0]
     ~@body
     *counter*))

(defn my-fn []
  (set! *counter* (inc *counter*)))

Чтобы продемонстрировать, попробуйте:

(with-counter (doall (repeatedly 5 my-fn)))
;; ==> 5

Для получения дополнительной информацииинформация см. http://clojure.org/vars#set

0 голосов
/ 12 сентября 2011

Вы можете сохранить экземпляр ThreadLocal в ссылке. И каждый раз, когда вам нужно увеличить его, просто прочитайте значение, увеличьте его и установите обратно. В начале запроса вы должны инициализировать локальный поток с 0, потому что потоки могут быть повторно использованы для разных запросов.

...