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

Reply via email to