Transactional File System Operations

24. January 2009

UPDATE: The use of TxF and KTM for long running transactions is not good.

Most of us are familiar with Transactions from the ADO.NET. To briefly explain what a transaction is, I can say that in a transaction, all operations occur in all-or-none basis. If an exception occurs and transaction is rolled back, then the system is in exactly the state it was before all those operations.

During our work on BlogSharp, I realized that I need to have transaction support for File System Operations. The scenario was simple, the author tries to create a post, upload some images and files. The user may save the post, or cancels it. Until now, it is easy to deal with those cases, but there is the third case: User may close the browser directly(or because of an exception). Keeping track of file and deleting them when they are no longer used is easy but it is not the way it should be. A better solution is possible with the use of transactions.

I searched if someone else had the same need, and found out that Martijn Boland(from Cuyahoga) gave it a try here using Castle Transactions. He uses a temporary directory to do the file operations, and after commit he copies them back to final location. This is definitely a good way of doing it.

However, I wanted to see if the file system supports transactions natively, and the answer turned out to be yes and no. NTFS of XP doesn’t support transactions while that of Vista(and Win2k8) does. I also learnt that Vista has kernel transactions via Kernal Transaction Manager which can be used against registry, too. Imagine an installer which doesn’t use its own transaction mechanism but KTM. When an error occurs, there will be no left overs since the transaction is not committed. The MSDN Magazine has an article that goes deep in this topic and provides some managed classes around TxF but I don’t like it. I then found Michael Kennedy's implementation here and it was better than the previous one. However, it still doesn’t provide any abstraction which I need for testing purposes. I gave it a go, too and here is the result:

[Fact]
public void Open_write_returns_stream_to_be_written()
{
    string data;
    using (TransactionScope scope = new TransactionScope())
    {
        
        using (var fileStream = fileService.OpenFileForWrite(this.textfile))
        {
            Assert.True(fileStream.CanWrite);
            Assert.False(fileStream.CanRead);
            Assert.True(fileStream.CanWrite);
            fileStream.Write(new byte[] {126}, 0, 1);
        }
        data = GetFileContentTransactional(this.textfile);
        Assert.Equal("~lah", data);
    }
    data = GetFileContentNonTransactional(this.textfile);
    Assert.Equal("blah",data);
}


I change the file content in transaction, and this change is only valid within the transaction. Unless we complete the scope, the change doesn’t take effect.

Please note that this is a managed wrapper with many many simplifications which may lead to improper results. It is by no means a production quality code. I have written many tests for basic cases but not advanced ones which may include file security problems. Moreover, there is no exception handling mechanism taking place to convert native I/O exceptions to human readable ones. There may also be memory leaks somehow(even though i paid special attention to this). Those mean that use it at your own risk. All feedback is welcome.

The native methods for transactional file operations can be found here.
The managed wrapper with FS abstractions can be found here

kick it on DotNetKicks.comShout it

, ,

Say Hello To ALT.NET Turkiye

10. January 2009

Alt.Net Turkiye This week has given birth to many ALT.NET local user groups, including Turkish community. If you’re reading this post, and looking for a place to ask your question on software or to share your ideas we invite you to join.

We are now at the planning stage, we’re trying to decide what to do and how we can introduce alt.net concepts to Turkish developers, but make sure you keep an eye on this group. Watch us grow.

,

Why I won’t buy a Dell again!

10. January 2009

It has been 1.5 years since I bought Dell D830. To summarize my experience, it was terrible.

First thing is that the battery died at 13th month,, 1 month after the warranty for battery expired. Now I am using my laptop as a desktop since I have to plug it to an AC all the time. The new battery was costing 299$ at that time, which is way too much. Now it costs 189 $ and I still think it is expensive.

Another recent issue is that the LCD started to blink, and sometimes this blink becomes permanent(ie remains black even after a reboot) and it comes when the BIOS re-installs itself. I am currently using the latest BIOS revision available (A14) and it didn’t solve my problem. At the time I am writing this post, it happened again.

OK, you may think that it’s electronics and some production issue may happen etc. Here is another thing: The International Warranty. Dell offers something similar to international warranty, called Transfer of Ownership, by which you can transfer your warranty to another country(I bought dell at the states and then come back to Turkey). I filled the form, then I received a mail that it may take around two weeks since there is some paperwork involved. It was acceptible. I wait around 1 month to contact the support and the guy told me that the application is still in progress and when it is done, I would receive an email. It is the 4th month and I am still waiting for it. I sent several emails but received no attention.

The bad thing is that, bad things happen when you need it most. I have final exams at the moment and I depend heavily on this laptop.

Enough is enough, Dell, you lost at least one real customer and several potential customers(my friends).

, , ,

Is lambda a syntatic sugar, or Turkish delight?

1. January 2009

We had been discussing on twitter+gtalk if lambdas are syntatic sugar or not. According to wikipedia, a syntatic sugar is a term coined by Peter J. Landin for additions to the syntax of a computer language that do not affect its functionality but make it "sweeter" for humans to use. Based on this description, what I see is that: We could build up an expression tree with a bunch of method calls before c# 3.0, but now we have an easier way of building it. It was even possible to build an expression tree runtime (take a look at db4o native queries and mono project). Moreover, lambdas aren’t just for expressions but also they can be converted into delegates.

Let’s do some demonstration now:

Action<MyClass> myAction=x=>x.Increment();


This piece of code is translated into following code

private static void Main(string[] args)
{
    Action<MyClass> myAction = (CS$<>9__CachedAnonymousMethodDelegate1 != null) ? CS$<>9__CachedAnonymousMethodDelegate1 : (CS$<>9__CachedAnonymousMethodDelegate1 = new Action<MyClass>(Program.<Main>b__0));
}

(Please note that our lambda has been converted into another ordinary method at compile time)
This code could have been written using ordinary C# syntax.

As you know, Lambas can also be converted into an expression depending on the context:

Expression<Action<MyClass>> myExpression = x => x.Increment();


This one, for example, will be translated into

private static void Main(string[] args)
{
    ParameterExpression CS$0$0000;
    Expression<Action<MyClass>> myExpression = Expression.Lambda<Action<MyClass>>(Expression.Call(CS$0$0000 = Expression.Parameter(typeof(MyClass), "x"), (MethodInfo) methodof(MyClass.Increment), new Expression[0]), new ParameterExpression[] { CS$0$0000 });
}


Now instead of into method/delegate, lambda has been converted into an expression, which can be done using an existing C# syntax.
One thing to note, Lambda itself has nothing to do with expressions. They can be converted into Expressions and then it is a piece of code that make something with those expressions (means that expressions can be interpreted by some providers) but it is a _short cut_ of doing it.

After those examples, one of my friends told that if we are talking about IL/CLR syntatical sugars, then they would agree. We can also extend this statement into “any programming language other than assembly (or basically 101001000s) is a syntatical sugar.” I would have agreed if I hadn’t known the definition of programming language.

For me, the syntatical sugars of C# language are the followings:
  1. The using statement
  2. The var keyword
  3. Lambdas
  4. Anonymous methods
  5. The dynamic keyword
  6. Automatic properties
  7. Object/Collection initializers

On the other hand, Generics, for example, is not a syntatical sugar. It doesn’t fall into another code within the same language. I am not sure about if this definition is valid, but this is the way I think it.

Just my 2 ykrs, I am trying to draw the boundaries of a syntatical sugar, and this post, hopefuly, will serve this purpose.

kick it on DotNetKicks.com