ok so now i'm totally confused, since I cannot see why the behaviour is so
different between beta1 and beta 2 ...

2011/8/30 Laurent PETIT <laurent.pe...@gmail.com>

> Congratulations, you've found a bug in clojure 1.3 beta2, see:
>
>  look with my clojure 1.2.0 version :
>
> ;; Clojure 1.2.0
> => (def thread (agent "Thread"))
>    (def account (ref 1000))
>    (send thread
>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
> agt))
>          account)
>    (time (dosync (ref-set account 2000)))
> #'user/thread
> #'user/account
> #<Agent@7e543cb1: "Thread">
> "Elapsed time: 0.498106 msecs"
> 2000
> => ;; 10 seconds later :
> => @account
> 2100
>
>
> And now with clojure 1.3 beta1 :
>
> ;; Clojure 1.3.0-beta1
> => (def thread (agent "Thread"))
>    (def account (ref 1000))
>    (send thread
>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
> agt))
>          account)
>    (time (dosync (ref-set account 2000)))
>    ;; 10 seconds later :
> #'user/thread
> #'user/account
> #<Agent@6bf51e5c: "Thread">
> "Elapsed time: 0.270225 msecs"
> 2000
> => @account
> 2100
>
> And now with Clojure 1.3-beta2
> ;; Clojure 1.3.0-beta2
> => (def thread (agent "Thread"))
>    (def account (ref 1000))
>    (send thread
>          (fn [agt aref] (dosync (alter aref + 100) (Thread/sleep 8000)
> agt))
>          account)
>    (time (dosync (ref-set account 2000)))
> #'user/thread
> #'user/account
> #<Agent@50fba502: "Thread">
> "Elapsed time: 7957.328798 msecs"
> 2000
>    ;; 10 seconds later :
> => @account
> 2000
>    ;; 10 more seconds later :
> => @account
> 2000
>
> 2011/8/30 Laurent PETIT <laurent.pe...@gmail.com>
>
>> 2011/8/29 Dominikus <dominikus.herzb...@gmail.com>
>>
>>> Thanks a lot for this detailed analysis and the pointers to the Java
>>> implementation, Stefan! That's excellent and very helpful.
>>>
>>> I still wonder, why the first transaction blocks write access. My
>>> overall understanding of the transaction system is that changes to
>>> referenced values remain in-transaction before committing them, a
>>> write-lock shouldn't be needed. I'm surprised, that the second
>>> transaction is the one who has to retry 71 times even though the first
>>> transaction hasn't committed anything yet.
>>>
>>
>> I must confess this behaviour also challenges my assumptions.
>>
>> Does this work the same whatever the clojure version used ?
>>
>>
>>>
>>> Cheers,
>>>
>>> Dominikus
>>>
>>> P.S.: Thanks for the idea to use 'future' to spawn a thread!
>>>
>>> On Aug 29, 5:42 pm, Stefan Kamphausen <ska2...@googlemail.com> wrote:
>>> > The call to alter already wrote to the Ref, this requires a write-lock
>>> on
>>> > the ref (see LockingTransaction.java/doSet).  After that it sleeps a
>>> while
>>> > and gets to its commit phase.  The other transactions retries in the
>>> > meantime.  Consider the following code, which introduces some atoms for
>>> > counting the retries
>>> >
>>> > (defn tz []
>>> >   (let [rr (ref 10)
>>> >         a1 (atom 0)
>>> >         a2 (atom 0)]
>>> >     (println "Starting future")
>>> >     (future
>>> >      (dosync
>>> >       (swap! a1 inc)
>>> >       (alter rr + 100)
>>> >       (Thread/sleep 8000)))
>>> >     (println "Sleeping a bit")
>>> >     (Thread/sleep 1000)
>>> >     (println "Another dosync")
>>> >     (time
>>> >      (dosync
>>> >       (swap! a2 inc)
>>> >       (ref-set rr 1)))
>>> >     [@rr @a1 @a2 (.getHistoryCount rr)]))
>>> >
>>> > user> (tz)
>>> > Starting future
>>> > Sleeping a bit
>>> > Another dosync
>>> > "Elapsed time: 7001.554 msecs"
>>> > [1 1 71 0]
>>> >
>>> > Note, how the 71 retries nice fit the approximately 7 seconds left and
>>> the
>>> > 100 miliseconds time-out (LOCK_WAIT_MSECS)  for the lock used in
>>> > LockingTransaction.java/tryWriteLock.
>>> >
>>> > Transactions with significantly different run-times should be avoided,
>>> > although there is some point at which older transactions will get their
>>> > turn.  This could be another explanation of the effect.  Take a look at
>>> the
>>> > barge-function in LockingTransaction.java
>>> >
>>> > Hope this helps,
>>> > Stefan
>>>
>>> --
>>> 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 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