Archive for December, 2007

Turbocharging .Net Webservice Clients

Saturday, December 15th, 2007

Since the first version of .Net and its associated toolset, Microsoft have sought to make it easy to write SOAP services and SOAP clients. And, generally, they have succeeded quite well. Whilst the open-source world has tended to prefer the simpler REST approach, MS (and Sun, and Apache) have done an admirable job of taking the large, complex SOAP protocol and making it reasonably straightforward to work with most of the time.

One of the areas in which things get somewhat less straightforward is high performance. Granted, most web services don’t have particularly eye-popping requirements in terms of hits or transactions, but occasionally you find an exception. Betfair, for instance, have an API that has peak rates in excess of 13,000 requests per second, many of which hit the database, with individual users making tens or even hundreds of requests per second. Betfair’s data changes at a breathtaking rate and there is a perceived advantage to getting hold of up-to-the-millisecond information.

To put that in context, the Digg Effect is estimated to peak at around 6K-8K hits per hour as I write in December 2007, which translates to a piffling couple of hits per second (8000 / 60 / 60 = 2.2). Even a more extreme prediction of 50K hits per hour is only around 14 hits per second, so we’re talking about handling three orders of magnitude more requests than Digg generates.

If you are writing a .Net client and want to get the best out of this sort of situation, you are hamstrung unless you learn a few tricks. Read on to learn five of the best. I’ll be using the Betfair API as an example throughout, but the techniques apply to any high-performance web service where the usage profile involves frequent small (<1KB) SOAP requests.

For those who normally turn to the back of the book for answers and don’t really care about the whys and wherefores, here’s the executive summary:

  1. Switch off Expect 100 Continue. This should be done in your App.config file (see below).
  2. Switch off Nagle’s Algorithm. This should be done in your App.config file (see below).
  3. Use multithreading. Unfortunately this is not a simple configuration file setting, it is a fundamental part of your application design.
  4. Remove the maximum connection bottleneck. This should be done in your App.config file (see below). This is vital if your application is multithreaded.
  5. Use gzip compression. .Net 2 has this built-in if you switch it on; .Net 1.1 needs a helping hand.

The XML snippet that configures these settings is shown below, and should be added to your App.config file:

<system.net>
    <connectionManagement>
        <add address=“*” maxconnection=“20″ />
    </connectionManagement>
    <settings>
        <servicePointManager
            expect100Continue=“false”/>
        <servicePointManager
            useNagleAlgorithm=“false”/>
    </settings>
</system.net>

For those who share my distrust of unexplained sorcery, here’s the gory details.

Expect-100 the Unexpected

RFC 2616 (the specification for HTTP 1.1) includes a request header and response code that together are known as ‘Expect 100 Continue’. When using the Expect header, the client will send the request headers and wait for the server to respond with a response code of 100 before sending the request body, i.e. splitting the request into two parts with a whole round-trip in-between.

Why would you ever want to do this? Well, imagine you are trying to upload a 101MB file to a web server with a 100MB file size limit. If you just submit the whole thing as one request, you’ll sit there for ages waiting for the upload to complete, only to have it fail right at the last minute when you hit the 100MB limit. Using Expect 100 Continue, you submit just the headers initially, and wait for the server’s permission to continue; in our example, this gives the server a chance to look at the Content-Length parameter and identify that your file is too big, and return an error code instead of permission to continue. This way you know the upload will fail, without needlessly transmitting a single byte of the large file.

By default, the .Net Framework uses the Expect 100 Continue approach. Most SOAP requests are not, however, anywhere near 101MB in size, and a server designed to deal with thousands of requests per second is not likely to be returning anything other than 100 Continue if the Expect header is sent. Depending on latency, the round-trip penalty may be unacceptable.

For example, Betfair’s Australian exchange (physically located in Australia) contains all their Australian markets, so if you’re in the UK and want to trade on the Australian Open tennis you’re subject to a round-trip time of about 350ms. If you allow your requests to be split into two, then you have two round-trips, so your request will take 700ms plus processing time.

You don’t want that, so switch it off. Note that the request headers and body are still sent separately, but the latter is no longer dependent on the response to the former (so they are shown as sent together in this diagram).

The setting corresponding to this in the XML snippet above is:

<servicePointManager
            expect100Continue=“false”/>

Nagle’s Algorithm

Nagle’s algorithm is a low-level algorithm that tries to minimise the number of TCP packets on the network, by trying to fill a TCP packet before sending it. TCP packets have a 40-byte header, so if you try to send a single byte you incur a lot of overhead as you are sending 41 bytes to represent 1 byte of information. This 4000% overhead causes chaos on congested networks. A TCP packet size is configurable, but is often set to 1500 bytes, and so Nagle’s algorithm will buffer outgoing data in an attempt to send a small number of full packets rather than a huge amount of mostly empty packets.

Nagle’s algorithm can be paraphrased in English like this:

If I have less than a full packet’s worth of data, and I have not yet received an acknowledgement from the server for the last data I sent, I will buffer new outbound data. When I get a server acknowledgement or have enough data to fill a whole packet, I will send the data across the network.

Now, with our use case (frequent SOAP requests, each <1KB) a request doesn’t fill a packet, so requests are subject to buffering. Furthermore, as explained above, even with Expect 100 Continue switched off the request headers are still sent separately from the request body, so the body of the first request is buffered until the request headers reach their destination and the server sends back a TCP ACK.

Let us again consider a UK client communicating with Betfair’s Australian API. Your application issues two requests one for current prices and one for your current market position (Req1 and Req2 in the diagram below). Together, both these requests are less than 1500 bytes. The headers for the first request are transmitted, but Nagle’s algorithm buffers the request body, plus the whole second request, since they don’t fill a TCP packet.

Due to the round trip latency, the acknowledgment of the first request’s headers is not received for 350ms, so that is how long the requests are buffered for. When the requests do get sent, they too are subject to 350ms latency around the world, so again you end up with around 700ms added to each of your Australian API calls.

Without Nagle, we dispense with the buffering and send out our smaller packets immediately, saving a round-trip.

One word of warning - disabling Nagle can cause problems if you are on a highly-congested network or have overworked routers and switches, since it increases the number of network packets flying around. If you don’t own your network, or are deploying your web service client to a large number of users, you might want to think about this carefully as you won’t be popular if your software saturates the network. The setting corresponding to this in the XML snippet above is:

servicePointManager
            useNagleAlgorithm=“false”/>

Happenin’ Threads

This one should be pretty obvious. A single-threaded application can only do one thing at a time. A multi-threaded application can do multiple things at a time. So if, for example, you want to display some information and need to collate the results from four web service requests to build your view, calling them one after another is going to be slower than calling them all simultaneously (not to mention freezing your UI if you’re writing a WinForms application and making calls on the UI thread).

Explaining how to design and write multi-threaded .Net applications is way out of scope for this blog post, but any time you spend reading and learning about it either online or in books is going to be time well-spent. Go on, do it now. Also read the next section, otherwise your application will not get as much benefit as you expect.

Walk and Chew Gum

.Net, by default, has a bottleneck on simultaneous web service calls against the same host. This one catches loads of people out - they write clever multi-threaded applications that issue many, many requests, and never realise that beneath the application layer a lot of their requests are called in sequence rather than in parallel.

Tsk, damn Microsoft for unnecessarily crippling their framework, right? Well no, actually, since this is an example of Microsoft following standards and recommendations and is to be applauded, lest they go back to their old ways of “embrace and extend”. The recommendation in question is from RFC 2616 again, and states:

A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.

(RFC 2616, section 8.1.4)

.Net uses HTTP 1.1 persistent connections by default (this is a good thing - you don’t want to incur the cost of establishing a TCP connection with every request, especially if you have long round-trip times as well since it involves multiple round-trips), so MS have done the right thing and restricted processes to two simultaneous connections by default.

What does this mean for your application? It means that if you want to make 20 requests, and do so on 20 threads as recommended above, under the hood .Net only makes two at a time and queues the rest up. Therefore your 20 threads are wasted, as your throughput is no better than if you’d only created two threads, and innocent web servers are protected from overzealous clients.

When we know that we’re talking to an insane city-flattening Godzilla-on-steroids of a server, however, the two-connection limit is unreasonable and we can ramp-up safely. The corresponding setting in the XML snippet above is:

<connectionManagement>
        <add address=“*” maxconnection=“20″ />

Sorted. You can, of course, change the number 20 to whatever is appropriate for your application.

Warning: Do not, under any circumstances, get into the habit of configuring this for all your web service applications. With all 20 threads issuing one request per second, you are exceeding the 14-request-per-second Digg Effect example I used above; with this technique and enough bandwidth your application will be quite capable of taking a lot of websites down, and those that manage to weather the storm will probably blacklist your IP address and/or close your account. Only use this if you are absolutely sure the server is up to it and such aggressive behaviour is permitted by the owners.

Small is Beautiful

The last step is to enable compression on your responses. Depending on the nature of the service you are using, the value of this tip may vary, but it’s likely to be of some benefit given the number of requests per second we are issuing. Of course, it is dependent on the web service actually supporting compression, but it’s been a standard feature of just about every web server for years, so this shouldn’t be a problem.

Lets look at a worked example. The getMarketPrices response from the Betfair API is about 30KB of XML. If, as above, we have 20 threads issuing one request per second, and each thread is interested in prices from a different market, that’s about 600KB of data per second, which will quite easily saturate a lot of home broadband connections.

With gzip compression, however, each response comes down to about 5KB (XML compresses very well, generally, since it is just text with a lot of repetition and whitespace), so the 20 threads now demand a more manageable 100KB per second.

Great. So how do we use it? In .Net 2.0 and above it’s very easy - just set the EnableDecompression property of your web service proxy object (ignore IntelliSense, which incorrectly claims the value is true by default; it’s actually false by default, as stated on MSDN). For example, to get compressed responses from Betfair’s global server:

BFGlobalService service = new BFGlobalService();
service.EnableDecompression = true;

If you’re still using .Net 1.1, you have a bit more work to do, since support for gzip was inexplicably left out of the framework. First, you need to subclass the generated BFGlobalService proxy class, and override some key methods so you can a) include the Accept-Encoding header to tell the server that you understand gzip, and b) decompress the gzipped response before the XML deserializer sees it, otherwise it’ll choke.

public class BFGlobalWithGzip : BFGlobalService
{
    /// <summary>
    /// Adds compression header to request header
    /// </summary>
    protected override System.Net.WebRequest
         GetWebRequest(Uri uri)
    {
         HttpWebRequest request = 
             (HttpWebRequest)base.GetWebRequest(uri);

         // Turn on compression
         request.Headers.Add(“Accept-Encoding”,
             “gzip, deflate”);
         return request;
    }

    /// <summary>
    /// Decompress response before the Xml serializer gets
    /// its hands on it
    /// </summary>
    protected override WebResponse GetWebResponse(
        WebRequest request)
    {
        return new HttpWebResponseDecompressed(request);
    }

    /// <summary>
    /// Need to override this method if performing
    /// asynchronous calls, otherwise de-compression
    /// will not be performed and will throw an error
    /// </summary>
    protected override WebResponse GetWebResponse(
        WebRequest request, IAsyncResult result)
    {
        return new HttpWebResponseDecompressed(
            request, result);
    }
}

Next, implement the HttpWebResponseDecompressed class. This subclasses .Net’s WebResponse class and knows how to decompress a response if it has ContentEncoding ‘gzip’:

public class HttpWebResponseDecompressed : WebResponse
{
    private HttpWebResponse m_response;
    private MemoryStream m_decompressedStream;

    public HttpWebResponseDecompressed(WebRequest request)
    {
        m_response = (HttpWebResponse)request.GetResponse();
    }

    public HttpWebResponseDecompressed(WebRequest request,
        IAsyncResult result)
    {
        m_response = (HttpWebResponse)
            request.EndGetResponse(result);
    }

    public override long ContentLength
    {
        get
        {
            if (m_decompressedStream == null
                || m_decompressedStream.Length == 0)
                    return m_response.ContentLength;
            else return m_decompressedStream.Length;
        }
        set { m_response.ContentLength = value; }
    }

    public override string ContentType
    {
        get { return m_response.ContentType; }
        set { m_response.ContentType = value; }
    }

    public override Uri ResponseUri
    {
        get { return m_response.ResponseUri; }
    }

    public override WebHeaderCollection Headers
    {
        get { return m_response.Headers; }
    }

    public override System.IO.Stream GetResponseStream()
    {
        Stream compressedStream = null;

        if (m_response.ContentEncoding == “gzip”)
            compressedStream = new GZipInputStream(
                m_response.GetResponseStream());
        else if (m_response.ContentEncoding == “deflate”)
            compressedStream = new InflaterInputStream(
                m_response.GetResponseStream());

        if (compressedStream != null)
        {
            m_decompressedStream = new MemoryStream();
            int size = 4096;
            byte[] buffer = new byte[size];
            while (true)
            {
                size = compressedStream.Read(
                    buffer, 0, size);

                if (size > 0)
                    m_decompressedStream.Write(
                        buffer, 0, size);
                else
                    break;
            }

            m_decompressedStream.Seek(0, SeekOrigin.Begin);
            compressedStream.Close();
            return m_decompressedStream;
        }
        else return m_response.GetResponseStream();
    }
}

To decompress the data, we need a decompression library since .Net 1.1 doesn’t provide one. In most cases, SharpZipLib will do the business:

using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;

Now, when creating an instance of BFGlobalService you can use the gzip-supporting subclass and everything else happens automatically.

BFGlobalService service = new BFGlobalServiceWithGzip();

Fin

Jebus, that went on for a bit. Now, go forth and write high-performance clients at will - but heed the warnings about only doing this when you know the server is on-the-ball, because these tips really can cause havoc if used irresponsibly.

Legacy Code, Refactoring, and Ownership

Thursday, December 13th, 2007

Refactoring is good. Everyone knows that. Since Fowler popularised the concept with the seminal Refactoring: Improving the Design of Existing Code it’s become a staple of the industry, and has pride of place on many a bookshelf. In the many, many articles and discussions of the subject, the key goals and benefits of refactoring are generally taken to be the improvement of readability, testability, decoupling, and other similar worthy ideals. For me, however, there is another very distinct benefit, often overlooked. Fowler touches upon it, but doesn’t really develop it, early on in Refactoring:

I use refactoring to help me understand unfamiliar code. When I look at unfamiliar code, I have to try to understand what it does. I look at a couple of lines and say to myself, oh yes, that’s what this bit of code is doing. With refactoring I don’t stop at the mental note. I actually change the code to better reflect my understanding, and then I test that understanding by rerunning the code to see if it still works.

(Fowler, Refactoring, 1999)

By investigating a piece of code thoroughly enough to understand how it works, refactoring it to map directly on to your understanding, and reinforcing everything with good unit tests, you take ownership of the code. It’s yours now.

This is very important, psychologically. Almost every developer feels more at home with their own code than somebody else’s. That’s why you feel uncomfortable and deflated when, 20 minutes into deciphering a nasty bit of opaque gibberish, you realise it was something you yourself wrote a year earlier and subsequently forgot about.

When you refactor, you rewrite code to a greater or lesser extent. Having done so, the resulting feeling of ownership (alongside increased understanding, of course) makes the code much less scary. The benefit of this is less marked in agile methodologies or TDD, of course, since in those cases quite often the code you are refactoring was written by you anyway. Working with legacy code, though, it’s a big deal.

In the preface to Working Effectively With Legacy Code, Feathers asks “what do you think about when you hear the term legacy code?” (Feathers, 2004). He answers by stating that the standard definition is “difficult-to-change code that we don’t understand” and adds his own preferred definition which is, in essence, “code without tests”.

My own definition of legacy code would include, in many cases, code that isn’t mine. By ‘mine’ I don’t exclusively mean code I wrote personally; I also mean code written by my team, or even code written by people who sit a couple of desks down who I can go and pester about it (which is stretching the definition a bit, admittedly).

In short, legacy code for me is code that no longer has any accessible owner. Like a stray cat or dog, code without an owner goes feral. Refactoring is the process of taming feral code, but as with stray cats much of the benefit comes from re-homing. This is a vital process, even if a fairly unconscious one. When you first come face to face with some hideous 5000-line spaghetti monster of a function your heart sinks - how can anyone ever hope to understand that, let alone modify it safely? Especially if the only people that ever worked with it left the company 3 years ago?

Refactoring allows you to split this code up, create classes to better represent the problem domain, improve abstraction, add tests, and all that other good stuff; at the same time, the process of doing so makes the code yours. You make the decisions about the classes to create and the abstractions to introduce. You write the tests that ferret out all the little idiosyncrasies, and uncover the unwritten assumptions. By the end of the process, the code feels like yours. And that means that the next time you have to make a change there, you benefit from the double whammy of code that is not only well-written and tested, but recognisably yours; and that’s the kind of code that you won’t mind working with.

Coding by Convention

Sunday, December 9th, 2007

I’ve been meaning for a while to have a play around with Ruby on Rails, on the basis that anything generating so much hype over the last year or two deserves some level of investigation, if only to see whether the hype is justified. So, I spent a couple of days working through Agile Web Development with Rails and, well, it’s pretty nice. I can certainly appreciate a development environment that goes to such endearing effort to do work for you without getting in the way - a fairly tricky balancing act. I came to the book with a working knowledge of Ruby but zero practical exposure to Rails, and on top of that I’m not a web developer so could not bring much contextual experience to the table. Despite this, I worked through the book and ended up with a functional book-store application in about 15 hours. Not too shabby.

So how does Rails achieve such power and productivity? The answer is largely that Rails, more so than pretty much any other development environment I’ve used, leverages the power of convention. That is, if you stay ‘on rails’ and behave the way Rails wants you to, then in return you get a great deal of functionality for free. A kind of technological “you scratch my back, and I’ll scratch yours”. If you structure your application as Rails expects, then Rails will automatically hook everything up for you. If you name your database tables as Rails wants you to, and create the primary/foreign key id columns that Rails expects, then Rails will take care of all your object-relational-mapping needs for you. Sounds like a good deal, yes?

Rails doesn’t expect you to jump through all these hoops yourself though. It provides a number of useful scripts that you can use to perform the common tasks you want to do, in the way that Rails wants you to do them. Probably the best example of this is when you first start a new project. You ask Rails to create an application for you, with the name you specify, then off it goes - and creates 45 files in 37 directories, without you having to lift a finger.

$ rails dummy
      create
      create  app/controllers
      ...
      <snip>
      ...
      create  log/development.log
      create  log/test.log
$ find dummy/ -type f |wc -l
45
$ find dummy/ -type d |wc -l
37

Compare this to a newborn ASP.Net application created using the Web Site wizard in Visual Studio 2005:

$ find WebSite1/ -type f |wc -l
2
$ find WebSite1/ -type d |wc -l
2

A pretty substantial difference. And if you stay within the confines of Rails’ expectations when adding to the project - which is very easy to do since you are provided with more generators for creating models, controllers, and migrations (basically incremental DB deployment scripts) - then you end up with a nicely structured application in accordance with the hallowed principles of MVC design, and everything is glued together automatically. Create a new data model, and your controller is immediately able to load it from the database along with all its relational buddies in a nice aggregated object structure with just one line of code (as long as you remembered to add all the has_many and belongs_to calls, of course). Store that data object in a controller member variable, and your views can access it for display. Use one of the magical rake incantations and get a DB-backed session management system which will horizontally scale in a load-balanced environment. Run the script/console script and you are dropped into a fully interactive command-line environment similar to irb, where you can instantiate and interact with all your objects dynamically. Tail the development log and you can see all the generated SQL as it is executed, and even get indicated performance in terms of theoretical request-per-second capacity. It’s all just fab. Nothing spectacularly new, of course; each individual feature has been done before, but Rails pulls them all together very nicely indeed.

As I worked through the aforementioned book, however, it was very clear that without the guiding instruction of the esteemed Dave Thomas and DHH I’d be up the creek without a paddle, and that got me thinking. Programming by convention is all great and frictionless and wonderful as long as you know the conventions. Imagine, if you will, the sheer blank incomprehension of a maintenance programmer who’s never heard of Rails, sitting down to tweak a Rails application.

Wait, what? How can this happen? Surely everyone has heard of Rails by now? Nope, sorry, but the truth is that the majority of programmers are clock-punchers living in a single-language world who don’t read blogs, or play around with tech in their own time, and haven’t even heard of Linux, let alone Rails. Their single language will likely be an everyday static language like Java or C#, which will leave them ill-prepared for many of the dynamic tricks in idiomatic Ruby.

Ah, but surely the kind of forward-thinking proto-company that builds its product on RoR would never hire non-Ruby-savvy developers anyway? That might be the case if you drink the 37signals Kool-Aid and think that any RoR company is by default über-smart and infallible, but in the real world it doesn’t work like that; there are countless tiny non-technical companies out there with just one or two developers - I know, because I spent a few years working at one - and maybe their current developers are cool enough to use RoR, but when they inevitably leave and the tech-illiterate management hire a replacement, you can guarantee that the job spec will not include minor details like “must have at least heard of Ruby on Rails”.

So, our imaginary maintenance guy - let’s call him Ted - hired by a non-technical company to look after a web application, peers for the first time into the 37 directories (assuming no new ones have been added) and >45 files (since new ones will most certainly have been added), and nothing makes any sense. Even assuming Ted is smart enough to make reasonable guesses about Ruby syntax, and knows what MVC is, there’s no visible link between the different layers of the application. It isn’t clear how data is shuttled to and from the database. It isn’t clear why things don’t always work as expected when Ted tries to manually add new things, rather than using the Rails scripts (which he doesn’t know about), even when diligently trying to emulate the structure and layout of existing code. It all seems like sorcery. What is Ted to do?

The correct answer is to go and by a Rails book of course, or at least try and pick out the decent tutorials on the web (unfortunately, there’s a lot more chaff than wheat in this area, maybe a sign that Rails is becoming a bit more mainstream?). A few days of getting up-to-speed, and Ted achieves enlightenment and becomes mega-productive, and lives happily ever after. So coding by convention is a good thing, right?

Maybe.

I’m still uneasy about sorcery, and Rails is some of the most effective sorcery I’ve seen. The main problem is that, well, it’s sorcery. A couple of times in the 15 hours I spent going through Agile Web Development with Rails I hit problems. Not major ones, and always of my own making - some silly typo, or mistake coming from only having a working knowledge of Ruby rather than cosy familiarity. As is my wont, failure to spot the error after a cursory glance through the code led to a quick google search to see if I’ve hit a common problem, before resigning myself to going through the code in detail to sort it out (like all good programmers I’m a lazy devil).

On these periodic google jaunts I found lots and lots of forum posts and blog entries from people who, and let’s not mince words here, hadn’t the first clue what they were doing. People that had heard the Rails hype, bought the book (and probably the t-shirt), hit problems, and were now running around like a cargo cult expecting magic spells to solve all their problems. Restart WEBrick. rake db:sessions:clear. Roll the most recent migration back then forward again. None of these work? Sorry, can’t help. It reminds me of The IT Crowd’s “have you tried turning it off and on again?”.

I shouldn’t be harsh on these folks; at least they’re getting excited by Rails and are rolling up their sleeves and having a go, and no doubt some of them will succeed wildly and become far better, richer, more attractive programmers than I can ever hope to be. Also let me be clear that I think the productivity gains of software like Rails is a good thing, and Rails is certain to account for a good chunk of my tinkering time for the next few months. It worries me, however, when people try to run before they can walk, and the magic of coding by convention tends to encourage it.

I’ll leave it as an exercise for the reader to consider the implications of the fact that the sample application being conjured here by all these sorcerers’ apprentices is an e-commerce site, at a time when online fraud is skyrocketing.

I don’t mean to single out Ruby on Rails specifically, by the way, it’s just handy as an example due to its profile. Coding by convention is not new; if you want an older example of what happens when people are given programming tools that allow them to get something working - for fairly loose definitions of ‘working’ - without knowing much about what’s happening under the hood, then look at the atrocities committed with VB and databinding over the years.

Steve Yegge has a characteristically long and insightful rant on this subject, and is troubled by the difficulty of working out where to draw the line. The line, in this case, being the level of abstraction at which a programmer should understand a system - high enough not to be bogged down in insane detail (e.g. knowing how semiconductors work) but not so high that the role of programmer is reduced to that of sideshow conjurer, waving a cheap trick-shop wand and trusting to a higher power that everything will work out OK.

Maybe it’s just a generational disease. Maybe in ten years’ time all the apprentices who have graduated to fully-fledged sorcerers will be looking on in dismay at the young scamps creating Web 5.0 applications using Ruby on MagLev simply by burping commands into their Skype headsets, and writing cautionary blogs about the dangers of not knowing how to write a partial web template.

Theoretically, a perfect system - perhaps a descendant of Rails in the dim and distant future - would contain such exquisitely crafted assumptions and such frictionless conventions that it would never go wrong and always do the right thing. Thus, the need to understand anything at the lower level of abstraction required to sort out any problems is obviated, unless you are one of the very few Grand High Wizards who keep everything running smoothly. I don’t know whether it’s fortunate or unfortunate that such a system is unlikely to appear within my lifetime.

Reindenting a File in Vim

Friday, December 7th, 2007

I’m going to post a series of helpful Vim snippets here, particularly for features that I don’t necessarily use every day and hence forget about after a while. By posting them here, I’ve got a nice easy one-stop-shop for finding them.

The first tip is reindenting source code. Hitting ‘=‘ will reindent visually-selected code , or you can also use a motion to constrain the affected area. ‘gg=G‘ will reindent the entire file:

using System;

namespace IndentExample
{
public class Indent
{
public static void Main(string[] args)
{
Console.WriteLine("badgerbadgerbadger");
}
}
}

to

using System;

namespace IndentExample
{
    public class Indent
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("badgerbadgerbadger");
        }
    }
}

More info: http://www.vim.org/tips/tip.php?tip_id=83

Renault Save the Queen

Friday, December 7th, 2007

I don’t tend to go in for flag-waving patriotism a great deal. Whilst I think the armed forces deserve our respect and our thanks, I tend to find The Sun’s “Our Boys” rhetoric twee and jingoistic. Whilst I enjoy watching England play football (and anyone who’s watched them recently will know that’s not a statement to be taken lightly), the sound of Wembley stadium belting out God Save The Queen leaves me cold, and I can normally be found in the kitchen making a cuppa or opening another bottle of Bombardier during the last few minutes before kick-off.

So imagine my surprise when I finally got round to watching this week’s Top Gear last night and found myself with goosebumps at the end of Hammond’s F1 segment, where the Renault engineers hook the car up to a laptop and get the engine to belt out the national anthem.

So, what the hell has to be wrong with someone to be unmoved by 80,000 fans singing, but filled with national pride when a bloody car does it? The engine isn’t even English, it’s French!