Hi Caleb,

I see you're excited, that's good! :)

Some general comments:
* This looks more like a design for a transaction module than for a persistence 
engine. I don't see anything related to persistence in your proposal below. 
Your proposal could work on stuff others than storage, right?
* I was expecting to see some Store/Storage/Persistence interfaces with 
proposed APIs and explanation on how they could be implemented both with 
Hibernate and JCR for example. And the relationship with the proposed new Model 
defined.
* I was also expecting a strategy defined to migrate users from the current 
implementation of the storage to the new one

I noticed some discussions between Denis and you on IRC about all this. Does 
you latest findings change the proposal below?

Thanks
-Vincent

On Jan 10, 2011, at 2:15 PM, Caleb James DeLisle wrote:

> Hi,
> I have been working hard on filesystem attachments and I found that 
> synchronizing manual filesystem 
> transactions with automatic database transactions was a difficult job and I 
> needed a new tool to do 
> it. So I wrote what I am proposing to be the next XWiki Persistence Engine.
> 
> I'll start off with the fun part of the proposal, I have been calling it 
> xwiki-store so far but I am 
> so excited about the capabilities of this engine that I don't think it does 
> it justice to name it 
> "store" after the place on the corner with milk and eggs. I am proposing it 
> be named "XWiki 
> Persistence Engine", the directory will be renamed xwiki-persistence, the 
> artifact name 
> xwiki-core-persistence, and the package name org.xwiki.persistence. 
> Persistence is an attribute of 
> castles, mountains and redwood trees which I think is fitting for a 
> conservatively designed storage 
> engine.
> 
> Now a little explanation of what I'm so excited about:
> The common and error prone way of saving things in the database is to open a 
> transaction, enter a 
> try clause, do something then commit. If we catch an exception, then we 
> rollback.
> something like this:
> 
> begin transaction;
> try {
>   do something;
>   do something else;
>   commit;
> } catch (Any exception which may occur) {
>   rollback;
> }
> 
> There are 3 things which can go wrong. 1 we forget to begin the transaction, 
> 2 we forget to commit 
> and 3 we do not rollback properly. What makes things worse is often the 
> database will "assume we 
> meant to..." and things will work ok most of the time which makes things much 
> worse because bugs 
> will hide very well.
> 
> My answer to this problem is a class called TransactionRunnable. It provides 
> a set of 5 empty 
> methods to override: onPreRun(), onRun(), onCommit(), onRollback(), and 
> onComplete(). the exact 
> circumstances under which each are called is documented in the javadoc 
> comments here:
> http://svn.xwiki.org/svnroot/xwiki/contrib/sandbox/xwiki-store/xwiki-store-transaction/src/main/java/org/xwiki/store/TransactionRunnable.java
> I wrote TransactionRunnable twice, I wrote it, used it for attachments, then 
> after having real 
> experience as a user, I wrote it again.
> 
> To repeat our original example with TransactionRunnable you might say this:
> 
> public class DoSomethingTransactionRunnable extends TransactionRunnable
> {
>   public void onRun()
>   {
>     do something;
>     do something else;
>   }
> }
> 
> Now we can use another TransactionRunnable which opens and closes the 
> transaction for us.
> 
> StartableTransactionRunnable transaction = new HibernateTransactionRunnable();
> new DoSomethingTransactionRunnable().runIn(transaction);
> transaction.start();
> 
> the runIn() function allows us to run one TransactionRunnable inside of 
> another. Supposing we wanted 
> to reuse "do something else" in other places, we can make it a separate 
> TransactionRunnable and use 
> the runIn() function to hook it to our DoSomethingTransactionRunnable ie:
> 
> public class DoSomethingTransactionRunnable extends TransactionRunnable
> {
>   public DoSomethingTransactionRunnable()
>   {
>     new DoSomethingElseTransactionRunnable().runIn(this);
>   }
> ..
> 
> The only limitations on running TransactionRunnables inside of one another 
> are they cannot run more 
> than once and they cannot call themselves (this would be an infinite loop).
> 
> This pattern makes each job which is done on storage easily isolated and, as 
> I have so far 
> experienced, trivial to test. However, it still leaves the possibility that 
> we might forget that 
> DoSomethingTransactionRunnable must be run inside of a hibernate transaction. 
> I have devised a 
> solution for this too. Using generics, I offered a means for the author of a 
> TransactionRunnable to 
> communicate to the compiler what other TransactionRunnable their runnable 
> must be run in and without 
> explicit casting or defining of an intermediary runnable, this requirement 
> cannot be violated or 
> else it wouldn't compile!
> 
> Finally we have the issue of starting the runnable. Who's to say I won't be 
> tired one day and just 
> write new DoSomethingTransactionRunnable().start() without opening a 
> transaction first? If 
> DoSomethingTransactionRunnable cannot be safely run outside of a transaction 
> all it needs to do is 
> not extend StartableTransactionRunnable and it won't have any start function.
> 
> I have taken a multitude of very easy mistakes and given the author of a 
> TransactionRunnable the 
> tools to make it very hard for the user to make them. Also, since a 
> TransactionRunnable has no 
> reason to be very long (it can just branch off into another runnable) this 
> will make testing and 
> code review easy in the place where it is most important. This part of the 
> code is entirely generic 
> and has no dependence on hibernate or anything else.
> 
> I propose we move:
> contrib/sandbox/xwiki-store/xwiki-store-transaction/
> to:
> platform/core/xwiki-persistence/xwiki-persistence-transaction
> 
> And I will propose moving each additional piece in the coming days.
> 
> WDYT?
> 
> Caleb

_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs

Reply via email to