Thank you! Great question.

I couldn't devise a way to merge concurrent changes in a HashMap using 
Clojure's STM. A while ago I discussed it with Christophe Grand and he had 
his own idea about how to fix it: [1] and [2]. IIRC Christophe's solution 
may see a conflict even if there's no real conflict due to stochastic 
nature of the implementation.

I had this use case in my project that functions as a reservation system, I 
needed a way to add a record into the Map saying that a given device has 
been reserved by a given user. Since I didn't know all the devices in 
advance I needed a way to detect conflicts even if Key/Value pair is added 
for the first time or when it is removed completely.

[1] http://clj-me.cgrand.net/2011/10/06/a-world-in-a-ref/
[2] http://clj-me.cgrand.net/2012/09/21/follow-up-a-world-in-a-ref/


On Sunday, August 18, 2013 12:42:23 PM UTC+2, Hussein B. wrote:
>
> Great ! Congratulations!
>
> How it does compare with Clojure's builtin STM?
>
> Thanks.
>
> On Sunday, August 18, 2013 10:24:48 AM UTC+2, Ivan Koblik wrote:
>>
>> Hi All,
>>
>> Almost 4 years ago I developed STM with semantic concurrency control for 
>> my project at CERN. Main feature of this STM is the TransactionalMap that 
>> lets you merge concurrent changes. Library is heavily tested and is very 
>> stable. It has been used in production for the past 2 years.
>>
>> Recently I released it on GitHub:
>> http://entwined.koblik.ch (will redirect to 
>> https://github.com/CERN-BE/Entwined-STM)
>>
>> Since Entwined STM was designed to be used from Java I wrote a simple 
>> facade for it in Clojure that you can load with 
>>
>> (require '[cern.entwined.core :as stm])
>>
>> Entwined STM operates on a memory with a fixed structure, meaning that 
>> you have to define what and how many collections you want to have in your 
>> STM and this can't be changed after construction. To construct memory with 
>> 1 transactional map and 1 transactional queue run this:
>>
>> (def memory (stm/create-memory :map (stm/create-map) :queue 
>> (stm/create-queue)))
>>
>> It's impossible to access transactional entities outside of a 
>> transaction, to run a transaction you can use "intrans" macro
>>
>> (stm/intrans memory data (-> data :map (.put :key1 "value1")) true)
>>
>> (stm/intrans memory data (-> data :map (.get :key1))) ;-> "value1"
>>
>> First line puts [:key1 "value1"] pair into the map. True at the end of 
>> the body tells the memory to commit this transaction. intrans will initiate 
>> commit if body returns truthy value. Second line just shows that the change 
>> has been committed.
>>
>> A couple more words on the implementation: I used HashMap to implement 
>> the TransactionalMap, I copy the backing map for every transaction which 
>> may be expensive for some scenarios. Obvious solution would be to use 
>> Clojure's persistent map. Commits are eventually serialized and protected 
>> with a single lock. If you take a look at the Java source you'll see that 
>> Transaction interface has a second method "committed" that is called when 
>> commit is being done. I use this method to write to the hardware knowing 
>> that execution order of committed callbacks is the same as the commit order.
>>
>> I would greatly appreciate any feedback and suggestions. If you have any 
>> questions don't hesitate to ask here or email me directly. Documentation is 
>> still somewhat lacking and I'd be interested to know which parts of it 
>> should be improved first.
>>
>> Cheers,
>> Ivan.
>>  
>

-- 
-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to