On Sat, Nov 27, 2010 at 9:19 PM, Ken Wesson <kwess...@gmail.com> wrote: > On Sat, Nov 27, 2010 at 7:50 PM, Mike Meyer > <mwm-keyword-googlegroups.620...@mired.org> wrote: >> My simple web app >> (http://blog.mired.org/2010/11/x10-controller-in-clojure.html) has >> some stuff that needs to happen just once (in this case, opening the >> serial port). It's not clear how to get this to happen using ring. If >> I do it inside my ring handler, then it gets run on every request, and >> I have to check to make sure it's not run multiple times. If I run it >> outside the handler, then it gets run when I do "lein uberwar", which >> is simply wrong. >> >> When the deployment platform activates the war would seem to be the >> right time to run this ("war load time"?). So maybe this is a question >> that depends on the deployment platform, or war? However, a quick >> google search didn't turn up anything that looked interesting. >> >> Anyone got suggestions on how to set up code to be run when Jetty (or >> tomcat, or ...)? > > If it were an ordinary application, -main would be the obvious place > (or some module-init function eventually called from there). In this > case, though, I think your best bet may actually be a Java > lazily-initialized singleton that you access from Clojure, if > performance is an issue, or else the Clojure equivalent: > > (defmacro defsingleton [name init-sexp] > `(def ~name > (let [singleton-uninitialized# (Object.) > a# (atom singleton-uninitialized#)] > (fn [] > (let [x# @a#] > (if (= x# singleton-uninitialized#) > (do > (reset! a# ~init-sexp) > @a#) > x#)))))) > > user=> (defsingleton foo (do (println "foo initialized") 7)) > #'user/foo > user=> (foo) > foo initialized > 7 > user=> (foo) > 7 > > You can also abuse futures: > > user=> (def foo (future (do (println "foo initialized") 7))) > #'user/foo > user=> @foo > foo initialized > 7 > user=> @foo > 7 > > or delay/force, or even lazy-seq: > > user=> (def foo (drop 1 (take 2 (iterate (fn [_] (do (println "foo > initialized") 7)) nil)))) > #'user/foo > user=> (first foo) > foo initialized > 7 > user=> (first foo) > 7
Or memoize: user=> (defn foo [] (do (println "foo initialized") 7)) #'user/foo user=> (def foo (memoize foo)) #'user/foo user=> (foo) foo initialized 7 user=> (foo) 7 which actually is fairly close to what the defsingleton macro does. -- 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