Hi Omri, I guess I could, using an atom to indicate multiple disparate chunks of code will update it (all within the same thread) felt idiomatic. - the initial (binding) is at the transaction level, subject updates are within the transaction.
> On 26 May 2015, at 17:38, Omri Hurvitz <o...@vastseas.com> wrote: > > If you always access *callbacks* as a thread-local, IE in the same thread, > why do you need it to be an atom? You can just rebind it using set! instead > of swap!. > > Beyond that, I think that using thread locals this way is very useful when > you want to limit the need for implementations to know your specific > implementation. The other way would be to pass the transaction, or a generic > environment, around, which tends to be ugly and sometimes confusing. > > Just make sure not to use it a lot and to document well. > > Disclaimer - while I have many years of development experience, I am > relatively new to Clojure, but I read a lot of Clojure code at this point. > > On Saturday, May 23, 2015 at 6:16:15 AM UTC-4, Colin Yates wrote: > 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 > <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 > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout > <https://groups.google.com/d/optout>. -- 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.