Hi,

My use-case is that I need to have a bunch of state which differs for each 
(web) request but is accessible via a var. Specifically I need to allow 
code to access the current transaction and register one or callbacks that 
are executed if/after that transaction is committed.

In Java I would store these as thread locals as each web request comes in 
as a new thread. In Clojure, the equivalent seems to be dynamic binding. 

Am I right in thinking that the following infrastructure is correct, 
specifically the use of thread-bound?. And when would I use bound? rather 
than thread-bound?

To be clear, the outer 'service' will call 'do-in-tx', code evaluated as a 
result of 'do-in-tx' will access the current tx by calling 'with-tx'.

(def ^:dynamic *tx*)
(def ^:dynamic *callbacks*)

(defn- execute-in-tx [db f]
  (jdbc/with-db-transaction
    [tx db]
    (binding [*tx* tx]
      (f tx))))

(defn- execute-callbacks []
  (doseq [[id cb] @*callbacks*] (cb)))

(defn do-in-tx [db f]
  (when (thread-bound? #'*tx*)
    (throw (IllegalArgumentException. "Nested transactions are not 
supported!.")))
  (binding [*callbacks* (atom {})]
    (execute-in-tx db f)
    (execute-callbacks)))

(defn with-tx
  "Call back the specified function providing the current transaction.

  If there is no current transaction then an (IllegalArgument)Exception is
  thrown. "
  [f]
  (when-not (thread-bound? #'*tx*)
    (throw (IllegalArgumentException. "No transaction found!")))
  (f *tx*))

(defn register-cb [id cb]
  (when-not (thread-bound? #'*callbacks*)
    (throw (IllegalArgumentException. "No transaction found!")))
  (swap! *callbacks* assoc id cb))


-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to