[sip-comm-dev] FailSafeTransaction


#1

Hi all,

I'm here to present you the brand new failsafe transaction utility.
As you may know this class will provide you a way to ensure that a file in which you are writing always remains in a coherent state. This is simply done using the transactional model (begin then commit or rollback).

Now for the specialists and more concerned people (Alexander and Emil) here are some explanations of some choices I've made.
Of course, if anyone as any remark on this implementation, I'll be pleased to ear that.

So this implementation differs a little bit from the Alexander proposition because I'm not copying the original file to a backup file and then ask the user to work on this backup for three reasons :

- first I really dislike the idea of returning a new File and hope that this file and only this file will be used, I think that this solution may be dangerous if someone doesn't read the doc, simply start a transaction and write to the original file and commit.
So in my solution, the file is backed up but the user doesn't know anything about this backup copy and simply work on the original file

- this solution also involve that, if a read is made during a transaction, the correct value will be red (and not the one from the original file).

- and a commit operation is for me a simple delete instead of two rename and a delete in the other solution.

In structural terms, I finally decided to think it as an utility class to be more dev-friendly, easy to use and to fit a really intuitive concept: one class for one transaction and nothing more (no service constructed class nor static constructor).
I don't know if it's the best choice but to me, as a dev, I think that it's the most intuitive and easy to use way of doing it.

There are some improvements possibles on this implementation: for example, Alexander proposed a method which simply need two rename and a delete operation to commit a transaction. I should probably use this method instead of my copy, rename, delete algorithm for my rollback operation (keep in mind that commit and rollback operations are not the same as the Alexander version as I'm working on the original file).

WDYT ?

Ben

···

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#2

I like it. I'd like to see S-C (like any other app at this kind of
risk) always call a File class that has actual file access through a
method that can be subclassed or versioned to use your transaction
procedure. That way, authors of file access calls don't have to
explicitly code to your transactional model, but just let the File
object use the improved method. Perhaps with a File attribute that skips
the transactions (maybe for performance or deadlock conditions specific
to the caller) rather than using them by default.

···

On Thu, 2007-10-04 at 19:48 +0200, Benoit Pradelle wrote:

Hi all,

I'm here to present you the brand new failsafe transaction utility.
As you may know this class will provide you a way to ensure that a file
in which you are writing always remains in a coherent state. This is
simply done using the transactional model (begin then commit or rollback).

Now for the specialists and more concerned people (Alexander and Emil)
here are some explanations of some choices I've made.
Of course, if anyone as any remark on this implementation, I'll be
pleased to ear that.

So this implementation differs a little bit from the Alexander
proposition because I'm not copying the original file to a backup file
and then ask the user to work on this backup for three reasons :

- first I really dislike the idea of returning a new File and hope that
this file and only this file will be used, I think that this solution
may be dangerous if someone doesn't read the doc, simply start a
transaction and write to the original file and commit.
So in my solution, the file is backed up but the user doesn't know
anything about this backup copy and simply work on the original file

- this solution also involve that, if a read is made during a
transaction, the correct value will be red (and not the one from the
original file).

- and a commit operation is for me a simple delete instead of two rename
and a delete in the other solution.

In structural terms, I finally decided to think it as an utility class
to be more dev-friendly, easy to use and to fit a really intuitive
concept: one class for one transaction and nothing more (no service
constructed class nor static constructor).
I don't know if it's the best choice but to me, as a dev, I think that
it's the most intuitive and easy to use way of doing it.

There are some improvements possibles on this implementation: for
example, Alexander proposed a method which simply need two rename and a
delete operation to commit a transaction. I should probably use this
method instead of my copy, rename, delete algorithm for my rollback
operation (keep in mind that commit and rollback operations are not the
same as the Alexander version as I'm working on the original file).

WDYT ?

Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

--

(C) Matthew Rubenstein

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#3

Hey Ben,

Thanks a lot for committing this. I really think that this is a valuable
utility as losing configuration files is a really serious usability
issue. I've had a look at your code and it is specless as usual. Good
job, Thanks!

(more inline)

Benoit Pradelle wrote:

Hi all,

I'm here to present you the brand new failsafe transaction utility.
As you may know this class will provide you a way to ensure that a file
in which you are writing always remains in a coherent state. This is
simply done using the transactional model (begin then commit or rollback).

Now for the specialists and more concerned people (Alexander and Emil)
here are some explanations of some choices I've made.
Of course, if anyone as any remark on this implementation, I'll be
pleased to ear that.

So this implementation differs a little bit from the Alexander
proposition because I'm not copying the original file to a backup file
and then ask the user to work on this backup for three reasons :

- first I really dislike the idea of returning a new File and hope that
this file and only this file will be used, I think that this solution
may be dangerous if someone doesn't read the doc, simply start a
transaction and write to the original file and commit.
So in my solution, the file is backed up but the user doesn't know
anything about this backup copy and simply work on the original file

I very much agree. File writing in Java is not handled through File
itself, but through streams and writer objects (and there are good
reasons for this). Failsafe writing is just another kind of file writing
so it should definitely be in an outside tool and not in an extension of
the File object.

- this solution also involve that, if a read is made during a
transaction, the correct value will be red (and not the one from the
original file).

Good point!

- and a commit operation is for me a simple delete instead of two rename
and a delete in the other solution.

Again, good point.

In structural terms, I finally decided to think it as an utility class
to be more dev-friendly, easy to use and to fit a really intuitive
concept: one class for one transaction and nothing more (no service
constructed class nor static constructor).
I don't know if it's the best choice but to me, as a dev, I think that
it's the most intuitive and easy to use way of doing it.

Actually I expected you'd implement this in the file access service. It
is true that having it inside util slightly simplifies its usage but
this is really a matter of only retrieving a reference to the
FileAccessService and from then on things are exactly the same.
Retrieving this reference corresponds to 4 or 5 lines of code per bundle
using the transaction. People that would be using this utility would
already have to be aware of the FileAccessService since they would be
using it for putting their file in the configuration home or a temporary
location. So I think it is safe to assume that it wouldn't be a problem
for them to instantiate a FailSafeTransaction through the
FileAccessService.

On the other hand, while in util, the transaction class would not
benefit from things that come with OSGi. In the case of the failsafe
transaction these would be:

* dependency management. it is true that now we don't even have it for
bundles using the OSGi servies but we soon will, and when we do, most of
the code that is using functionality through OSGi services would be
easily adapted to benefit from it.

* easily change implementations. We've seen several different ideas
before you actually implemented the service and probably others would
come in the future. Some day someone might actually create a super lib
that handles failsafe writing really gracefully and we may want to start
using it. Obviously the re-coding itself would not be that problematic
in either case. In the case of a service handled transaction mechanism,
however, you'd be able to actually switch one for the other without
recompiling or even without stopping the project. You could deploy
different versions of the project, each running a different
implementation depending on the OS/architecture it will be running on.
Failsafe writing is a very important and delicate thing (which is why I
am so glad you did it :slight_smile: ) so we need to treat it as such.

* exposure and usability. As I mentioned earlier, people that use the
failsafe transaction would most probably already be using the
FileAccessService so if the transaction mechanisms are in there, they
are likely to notice them. Keeping them in util, however, would take out
visibility and people would probably not be seeing them unless they
explicitly look for them.

* conformity with the rest of the architecture. this one speaks for
itself :).

So what do you think?

Cheers!
Emil

···

There are some improvements possibles on this implementation: for
example, Alexander proposed a method which simply need two rename and a
delete operation to commit a transaction. I should probably use this
method instead of my copy, rename, delete algorithm for my rollback
operation (keep in mind that commit and rollback operations are not the
same as the Alexander version as I'm working on the original file).

WDYT ?

Ben

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#4

Hi Emil, all,

Emil Ivov a �crit :

Hey Ben,

Thanks a lot for committing this. I really think that this is a valuable
utility as losing configuration files is a really serious usability
issue. I've had a look at your code and it is specless as usual. Good
job, Thanks!
  
Thanks :slight_smile:

(more inline)

Benoit Pradelle wrote:
  

Hi all,

I'm here to present you the brand new failsafe transaction utility.
As you may know this class will provide you a way to ensure that a file in which you are writing always remains in a coherent state. This is simply done using the transactional model (begin then commit or rollback).

Now for the specialists and more concerned people (Alexander and Emil) here are some explanations of some choices I've made.
Of course, if anyone as any remark on this implementation, I'll be pleased to ear that.

So this implementation differs a little bit from the Alexander proposition because I'm not copying the original file to a backup file and then ask the user to work on this backup for three reasons :

- first I really dislike the idea of returning a new File and hope that this file and only this file will be used, I think that this solution may be dangerous if someone doesn't read the doc, simply start a transaction and write to the original file and commit.
So in my solution, the file is backed up but the user doesn't know anything about this backup copy and simply work on the original file
    
I very much agree. File writing in Java is not handled through File
itself, but through streams and writer objects (and there are good
reasons for this). Failsafe writing is just another kind of file writing
so it should definitely be in an outside tool and not in an extension of
the File object.

- this solution also involve that, if a read is made during a transaction, the correct value will be red (and not the one from the original file).
    
Good point!

- and a commit operation is for me a simple delete instead of two rename and a delete in the other solution.
    
Again, good point.

In structural terms, I finally decided to think it as an utility class to be more dev-friendly, easy to use and to fit a really intuitive concept: one class for one transaction and nothing more (no service constructed class nor static constructor).
I don't know if it's the best choice but to me, as a dev, I think that it's the most intuitive and easy to use way of doing it.
    
Actually I expected you'd implement this in the file access service. It
is true that having it inside util slightly simplifies its usage but
this is really a matter of only retrieving a reference to the
FileAccessService and from then on things are exactly the same.
Retrieving this reference corresponds to 4 or 5 lines of code per bundle
using the transaction. People that would be using this utility would
already have to be aware of the FileAccessService since they would be
using it for putting their file in the configuration home or a temporary
location. So I think it is safe to assume that it wouldn't be a problem
for them to instantiate a FailSafeTransaction through the
FileAccessService.

On the other hand, while in util, the transaction class would not
benefit from things that come with OSGi. In the case of the failsafe
transaction these would be:

* dependency management. it is true that now we don't even have it for
bundles using the OSGi servies but we soon will, and when we do, most of
the code that is using functionality through OSGi services would be
easily adapted to benefit from it.

* easily change implementations. We've seen several different ideas
before you actually implemented the service and probably others would
come in the future. Some day someone might actually create a super lib
that handles failsafe writing really gracefully and we may want to start
using it. Obviously the re-coding itself would not be that problematic
in either case. In the case of a service handled transaction mechanism,
however, you'd be able to actually switch one for the other without
recompiling or even without stopping the project. You could deploy
different versions of the project, each running a different
implementation depending on the OS/architecture it will be running on.
Failsafe writing is a very important and delicate thing (which is why I
am so glad you did it :slight_smile: ) so we need to treat it as such.

* exposure and usability. As I mentioned earlier, people that use the
failsafe transaction would most probably already be using the
FileAccessService so if the transaction mechanisms are in there, they
are likely to notice them. Keeping them in util, however, would take out
visibility and people would probably not be seeing them unless they
explicitly look for them.

* conformity with the rest of the architecture. this one speaks for
itself :).

So what do you think?
  
I agree with you, it's probably a better idea to access to these transaction using the FileAcessService, I'll move all the failsafetransaction stuff to this package and create a constructor in this service. It should not break too much my original idea of simplicity and will involve all the benefits you explained.

Cheers,
Ben

···

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net