Yes, it uses agents for writing operations. So on the account of disk failure it's possible that in-memory state will be a few transactions ahead of what is actually persisted. Thus it's not a strict transactional solution.
I consider it as a good fit for project prototyping and may be production systems where this non strict behavior is acceptable. (considering people test it enough first) The in-crash behavior can be slightly improved by adding additional agent which will persist transactions by sending them to a remote computer, but of course it's not a fully reliable solution either. On Thu, Dec 10, 2009 at 11:30 AM, Laurent PETIT <laurent.pe...@gmail.com>wrote: > Hello, > > without going too deep in the detail of your implementation, I just can't > keep thinking that, as far as I know, it's currently impossible with clojure > to extend the scope of the transaction outside the STM, without changes in > the STM itself (STM being aware of TransactionManagers being certainly the > way to go, I guess). > > At least, making it 100% reliable and race conditions-free. > All of this due to the fact that you can't do side effets from within the > transaction, and you have to use an agent to do so. And when the agent will > do the real persistence call, if this call fails for some reason (wire > disconnected, etc.), it's too late to fail the STM transaction, it's already > finished and commited to the ref world. > > Did I miss something ? > > 2009/12/2 Sergey Didenko <sergey.dide...@gmail.com> > >> Hi, >> >> I have implemented the simple journal-based persistence library for >> Clojure programs and now making it public. >> >> It follows "Prevalent system" design pattern. >> >> I consider it a good fit for the prototyping stage of a project >> development. When you don't want to pay the price of impedance mismatch >> between the language data structures and your database because your database >> schema is not stable yet. >> >> However this pattern is used in production by some teams, see Prevayler >> mail list for details. Of course this implementation can contain bugs and >> must be tested well before doing that. Though it is very simple and I made >> some tests. >> >> The disadvantage of the pattern is that your data structures must fit in >> memory (unless you implement ad-hoc paging solution). However the journaling >> nature lets you easily switch to other databases. For that you just >> re-implement your transaction functions (subjects of apply-transaction* ) to >> write/read from another DB and replay transactions one time (init-db). >> >> Snapshotting is not yet implemented. It can solve another pattern problem >> - growing startup time. >> >> Usage examples: >> >> 1. first run >> >> (use 'persister) >> >> (def refx (ref 0)) >> (def refy (ref 0)) >> >> (defn tr-fn [x y] >> (do >> (alter refx + x) >> (alter refy + y) )) >> >> (defn tr-fn-swap [] >> (let [tmp @refx] >> (ref-set refx @refy) >> (ref-set refy tmp))) >> >> (defn tr-inc [] >> (ref-set refx (inc @refx)) >> (ref-set refy (inc @refy)) ) >> >> (init-db) >> (apply-transaction tr-fn 1 2) >> (apply-transaction tr-fn 10 20) >> (apply-transaction tr-fn-swap) >> (apply-transaction tr-inc) >> [refx refy] >> >> [#<r...@5bb966: 23> #<r...@1e903d5: 12>] >> >> 2. the second run >> >> (use 'persister) >> >> (def refx (ref 0)) >> (def refy (ref 0)) >> >> (defn tr-fn [x y] >> (do >> (alter refx + x) >> (alter refy + y) )) >> >> (defn tr-fn-swap [] >> (let [tmp @refx] >> (ref-set refx @refy) >> (ref-set refy tmp))) >> >> (defn tr-inc [] >> (ref-set refx (inc @refx)) >> (ref-set refy (inc @refy)) ) >> >> (init-db) >> [refx refy] >> >> [#<r...@5bb966: 23> #<r...@1e903d5: 12>] >> >> >> Note that journaled functions must be accessible in the current namespace >> when you replay transactions. >> >> See inline doc for details. >> >> Looking for your feedback! >> >> Regards, Sergey. >> >> -- >> 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<clojure%2bunsubscr...@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 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<clojure%2bunsubscr...@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 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