Stefan Tilkov on REST

by nick Sat, January 31 2009 13:30

An interesting presentation by Stefan Tilkov on REST and its principles.

I find that many people equate SOA with web-services and in turn, web-services with scalability and flexibility, because the web is scalable and flexible right?

The web really fired the debate about 'stateless' architectures being the key to scalability (actually this is the 'web' taking accolades that strictly belong to http but never mind). This is not so surprising - in the enterprise space, there are many problems of scale and in those enterprises, people's minds are often focused on what they can do to improve it. Http seemed a straightforward way to address this. Hence WS-*. In my opinion though, the scalability of some arbitrary system is a largely an issue for that system internally - it's entirely possible to build 'scalable-enough' systems without Fielding's thesis on your desk.. What often matters more, but is not addressed as aggressively, is the composition of these systems to form more useful composite systems.

The true benefit of a restful approach (for me) is the architectural style that deliberately defines a small number of verbs and a strict model for the use of those verbs. This seems to me to capture the essence of what is required for composition of services, particularly that 80% of composition which is unforseen. The difficulty of post-facto service composition is often what really hinders the emergence of real enterprise architecture and in turn why systems-integration (which is what much of enterprise development often really reduces to) can be such a fraught exercise. Using WS-* to wire your applications together is much like defining standards for electricity cabling and then requiring a unique plug-socket at the end of each individual cable.

Tags:

CCR Article on InfoQ.com

by nick Thu, January 29 2009 13:29

I have posted an introductory article on the CCR at infoq.com.

Tags:

George Chrysanthakopoulos on Channel 9

by nick Sun, January 18 2009 13:29

George talks to Erik Meijer, about coordination and (incidentally) concurrency.

Even if you’ve not used the CCR, it’s worth a watch. If his passion for an alternative to the existing mainstream programming models doesn’t at least raise your level of curiosity, then nothing will.

Tags:

IAsyncResult and WaitHandle lifetime

by nick Wed, January 07 2009 13:28

The BeginXXX/EndXXX asynchronous invocation pattern in .NET has BeginXXX return an IAsyncResult. In the past, I’ve not normally done anything with this, rather preferring to use the one passed into the callback e.g.

    var cmd = new SqlCommand();
    // Initialise the command... 
    cmd.BeginExecuteReader(iar =>
        {
            try
            {
                using (var rdr = cmd.EndExecuteReader(iar))
                {
                    // Deal with the results...
                }
            }
            catch(Exception e)
            {
                // Deal with the error...
            }
        }, null);

Surprisingly, this code has a subtle leak (of sorts). And it’s to do with a property of the IAsyncResult that’s not even used, the AsyncWaitHandle. Now this is normally only used if you really need to block to wait for the outcome of the operation, e.g.

    var conn = new SqlConnection(connstr);
    var cmd = new SqlCommand();
    // Initialise the command... 
    var iar = cmd.BeginExecuteReader();
    iar.AsyncWaitHandle.WaitOne();
    try
    {
        using (var rdr = cmd.EndExecuteReader(iar))
        {
            // Deal with the results...
        }
    }
    catch(Exception e)
    {
        // Deal with the error...
    }

The WaitHandle is really just a thin veneer a native Windows HANDLE, so when is it actually created and subsequently cleaned up? Well, unfortunately, it depends. The documentation advises implementers of IAsyncResult of two things

  1. The object that implements IAsyncResult does not need to create the WaitHandle until the AsyncWaitHandle property is read.
  2. (the) AsyncWaitHandle should be kept alive until the user calls the method that concludes the asynchronous operation. At that time the object behind AsyncWaitHandle can be discarded.

The italics are mine; what this means in practice is that you have to determine what your exact flavour of BeginXXX/EndXXX actually returns.

For example, the System.Data.SqlClient async operations return an IAsyncResult that both

  1. Eagerly creates the WaitHandle (regardless of whether you ever use it)
  2. Doesn’t actually dispose of the WaitHandle when EndXXX is called.

This means that, even if you use the first of the above two usage patterns and never explicitly reference the WaitHandle, at completion of the operation, the handle remains open until collected. But this could be a while, especially if the IAsyncResult was suspended long enough to get promoted through a GC generation or two. And if you hammer your database sufficiently, you’ll see a significant spike in the number of open handles in your process. You also incur the overhead of having the WaitHandle itself placed on the finalization queue.

In order to follow Microsoft’s own advice about eagerly disposing of unmanaged resources, we need to amend the first sample:

    cmd.BeginExecuteReader(iar =>
        {
            using (iar.AsyncWaitHandle)
            {
                try
                {
                    using (var rdr = cmd.EndExecuteReader(iar))
                    {
                        // Deal with the results...
                    }
                }
                catch (Exception e)
                {
                    // Deal with the error...
                }
            }
        }, null);

Extension methods can be used to reduce clutter and increase modularity:

    public static class SqlCommandExtensions
    {
        public static void BeginSafeExecuteReader(this SqlCommand cmd, AsyncCallback callback)
        {
            cmd.BeginExecuteReader(iar =>
                {
                    using (iar.AsyncWaitHandle)
                    {
                        callback(iar);
                    }
                }, null);
        }
    }

Which allows a solution very close to the original, but with deterministic disposal of the WaitHandle:

    cmd.BeginSafeExecuteReader(iar => 
        {
            try
            {
                using (var rdr = cmd.EndExecuteReader(iar))
                {
                    // Deal with the results...
                }
            }
            catch (Exception e)
            {
                // Deal with the error...
            }
        });

(By the way, the WaitHandle in the IAsyncResult returned from methods in the System.Net namespace is both lazily created and cleaned up on EndXXX, which means none of the above is necessary for async operations in that particular namespace).

Tags:

ReaderWriterLockSlim Extensions

by nick Mon, January 05 2009 13:27

The ReaderWriterLockSlim class is an improved implementation of useful locking functionality, but it doesn’t have the same syntactic support that Monitor does via the lock keyword, so you have to do the try/finally dance yourself. In addition, you must correctly unwind the particular lock (read or write) that you took originally.

In C#, extension methods and lambda syntax can go a little way to ameliorating this situation.

    public static class ReaderWriterLockSlimExtensions
    {
        public static void WithReadLock(this ReaderWriterLockSlim rwLock, Action action)
        {
            rwLock.EnterReadLock();
            try
            {
                action();
            }
            finally
            {
                rwLock.ExitReadLock();
            }
        }

        public static void WithWriteLock(this ReaderWriterLockSlim rwLock, Action action)
        {
            rwLock.EnterWriteLock();
            try
            {
                action();
            }
            finally
            {
                rwLock.ExitWriteLock();
            }
        }
    }

It then becomes possible to write:

    using (var rwLock = new ReaderWriterLockSlim())
    {
        rwLock.WithReadLock(() =>
        {
            // Blah
        });
    }

Tags: