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
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to