特定の関数がリクエスト (スレッド) で呼び出された回数を追跡できるようにしたい Web アプリがあります。
ref を使用してスレッド ローカル以外の方法で実行できることはわかっていますが、スレッド ローカルで実行するにはどうすればよいでしょうか。
特定の関数がリクエスト (スレッド) で呼び出された回数を追跡できるようにしたい Web アプリがあります。
ref を使用してスレッド ローカル以外の方法で実行できることはわかっていますが、スレッド ローカルで実行するにはどうすればよいでしょうか。
と呼ばれる便利なツールがありますthread-local
。たとえば、 と書くことができます(def counter (thread-local (atom 0)))
。これにより、グローバル変数が作成され、deref
ed のときにスレッドごとに新しいアトムが生成されます。したがって、現在の値を で読み取る@@counter
か、 でインクリメントできます(swap! @counter inc)
。もちろん、アトム自体を取得して、@counter
それ以降は通常のアトムのように扱うこともできます。
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
ThreadLocalのインスタンスをref に保持できます。そして、値を増やす必要があるたびに、値を読み取り、値を増やして元に戻します。スレッドは別のリクエストで再利用される可能性があるため、リクエストの開始時にスレッド ローカルを 0 で初期化する必要があります。