Archive for April 2008

Ross Noble

Amy and I went to see Ross Noble perform at the Canberra Theatre Centre last night. He is one of those rare people who can genuinely just talk and make funny, spontaneous observations about almost anything. He utilises that ability to construct a very random show that twists and turns, simply incorporating whatever he happens to think about. He is also a fan of self-referential humour, either by criticising his own actions or acting as he imagines an audience might at his antics.

Unfortunately for me its all just a bit too uneven. Ross is a fan of tangential observations, which when used to full effect can be very funny. Ross however seems unable to ignore tangents that are less funny than his current topic, leading to a show whose comedic value ebbs and rises.

The polished traditional comic seems to avoid this: in utilizing essentially the same stories each performance they can fine-tune jokes or simply drop them if the audience don’t react. Ross is unable to take advantage of this, and despite being incredibly gifted over a 2 hour period I definitely started to wish for a little bit more structure – or dare I say it – rehearsal.

That said, it was still a great show to watch; if only to watch a rare talent in action. Ross is capable of some incredibly humorous comments, and the spontanenous nature of his observations only adds to the appeal. Just don’t expect to be fully entertained for the full performance.

Ubuntu 8.04 released

Trog mentions that Ubuntu 8.04 has been released, with demand for it on Bigpond being higher than expected. I’ve been using Ubuntu as my primary desktop since its first release in late 2004 and it has been getting better and better with each release. While still very much a niche, I’m glad to see that the hard work going into making a usable linux desktop is apparently having some reward.

Trog also commented that he believed you could upgrade directly from the Ubuntu repository rather than having to download a new installation CD. This is true and in fact is very easy. To do so, you need to start the “Update Manager”:

Enter your administration password at the prompt. The Update Manager will detect a new release is available, at which point you just need to click the “Upgrade” button to install 8.04 LTS:

Foreign Soil

Last week I was in Brisbane (where I lived for the first 24 of my years) for work meetings. I travel here roughly every 3 months; its interesting to see what has changed since my last visit.

At the end of the first day I catch a taxi to the hotel. The taxi driver is the talkative type I abhor – personally I look forward to the robot taxi’s they have in some science fiction. He asks about where I obtained the jacket I am wearing and he is confused by my answer of “Parliament”. Do they not have that store here or is this guy just ignorant?

I have visited the hotel I have stayed in before; its the kind of place you dont want to spend any time in. Adequate for sleeping but the design sense is.. lacking. At least its clean.

Having established I’m not a local, the taxi driver moves to the obvious question of why I am here. My answer compels him to tell a story of when he once used Excel to average some numbers, from which he concludes computers are easy whilst also claiming he doesn’t understand them. What this story has to do with software development isn’t clear to me.

His computer story continues to some problem with his broadband and “Mozilla Firefox”. This intrigues me – both due to his prefix of Mozilla and that this apparently minimum-requirements computer user is not using Internet Explorer.

The final story of my trip is a confused tale of doing something in the registry. This is somewhat conflicting – why is this self-described computer illiterate person making changes to the registry. And where has the Windows-world gone wrong that people have to resort to this level of chicanery.

A perhaps little known fact is that Linux (or more precisely, Gnome) has a registry too. I don’t know much beyond that – I’ve never had to use it, and certainly don’t know what’s in there or why I might need to alter a setting.

During the meetings, I watched a coworker struggle to login to a Windows shared folder. He typed his login details into the popup box, and pressed enter. The window reappears – must be the wrong password? He tries again, and then a third time, each time giving the same result. Frustrated he gives up and presses “Escape” to cancel the action, at which point the folder he was trying to access appears.

I don’t know why the wider world – and particularly technical users – cling to Windows. The popular belief amongst the power users is that linux is somehow hard to use and yet somehow the ongoing grief Windows visibly causes these people is glossed over.

Rockbox does what Apple doesnt

Rockbox is an open-source alternate firmware for a variety of digital audio players, including a variety of iPods. In other words, its a complete replacement for the software that runs on the audio player that can provide a variety of features that Apple either can not or will not provide.

I had seen Rockbox mentioned on Slashdot a few times, but was not a big enough iPod user to investigate the software or what was involved in installing it. Recently however I’ve grown a bit tired of burning CD’s for my car and so have taken to utilising my iPod for this purpose.

Perhaps the biggest annoyance of using an iPod for more technical users is the requirement that all music be added via iTunes (or compatible software). I find this annoying for two reasons:

  • I have my music files stored on a NAS. It would be far more convenient if I could just synchronize those files directly onto the iPod instead of having to run a GUI application.
  • I dont use iTunes to play music on PCs. I’ve already organised my music into a hierarchical structure which I find is best suited to my needs; an ID3 databse (not just iTunes, but K3B’s too) just does not work as well for me.

Rockbox has many more features than Apple’s firmware, but easily the most desirable for me is the ability to just copy files directly to the iPod disk. When using Rockbox, I can then browse the folders I’ve uploaded and play them.

A feature I’ve found useful for utilising the iPod in the car is the configurable start-up action. Apple’s firmware has a feature that when plugged into a car adapter, the iPod pauses playback when the car is turned off. This is certainly useful, but unfortunately there does not appear to be a corresponding resume playback when power is turned on.

Rock maintains the pause functionality while also adding the ability to choose what to do when the iPod is powered on. You can choose to start in a specific area (like “Files”) or to “Resume Playback”. This suits me perfectly since I can just leave the iPod in my glovebox and not have to touch the thing unless I want to change albums.

Installation of Rockbox was surprisingly easy (extract a .zip onto the iPod hard drive, run a program, finished) and the PDF manual is thorough – at 100+ pages, I didnt get too far past the installation section. Beyond learning a few more keystrokes (”Prev” is go up directory / back in the settings tree) general usage is just as easy as Apple’s firmware. I would definitely recommend a look for power users; the “play files off the drive” feature is worth the price of admission alone.

When should you deploy a new build?

Working for a small company doing ongoing contract work for a large company, there can be often be disagreements over how to solve problems. Large companies like to solve problems with “process” – a series of steps that must be performed to carry out some task.

The key thing about a process is that it absolves everyone of responsibility: if you encounter failure after carrying out the process, it is the process at fault. Unfortunately process failure leads to process review, with the end result typically being more steps added to the process.

One process that is familiar to many developers is that of website deployment: the process of actually changing what’s online from an old release to a new release. At Mammoth we firmly believe in many of the tenets of agile development and so have a release every one to two weeks. We store our releases in Subversion so the actual mechanics of getting a new release onto the site are both easy and repeatable.

The matter of when during the day (or night) to actually deploy a build seems an easy answer at first. Let’s say for example that you have spent the day testing your application; its now 4pm and time to deploy. The deployment is carried out, and your database immediately falls over: it turns out your application has a bug that causes 1000 extra queries on a popular page.

This outrageous mistake has caused ten minutes of downtime until the deployment was rolled back to the prior release (you do have a rollback plan dont you?). At this point, the deployment process comes under attack: “Why is there a deployment at 4pm? We should deploy at 4am when no one is using the site!”

At first (and second) glance, this line of thought is hard to argue with and indeed this is the current process utilised by our client. And indeed it does appear to work – the site essentially never does crash immediately after being deployed.

Upon closer analysis though, this is not the least bit surprising. The load on our website at 4am is essentially the same as that created during testing. If the website was going to crash with this level of load, it already would have during the test process, hence meaning it would already be fixed.

So at this point everyone pats themselves on the back for another successful deployment and goes to bed. The reality is somewhat different however: what has been deployed is essentially a ticking time bomb. The site may very well still have a bug in it that when exposed to the level of load that 4pm entails, causes the entire site to crash.

This I think is the crux of why 4am deployments (on their own) are bad: it fosters a false sense of safety. Recall that our actual problem was that a defect caused the number of users at 4pm to crash the site. There is only one way to actually prevent this problem – ensure that such a defect is not in the site at 4pm. A couple of methods spring to mind as ways to prevent this:

  • Utilise a load testing process prior to each deployment. This should catch most your problems
  • Ensure there is adequate monitoring of your database, CPU, memory, etc resources that it is obvious when a defect causes a sudden day-over-day spike.

A secondary problem is that our client is rigid about the one-release-per-week: if a release doesn’t “take” the only option is to rollback. This creates somewhat of a quandry when combined with 4am releases – if you do not rollback until say 4pm, customers have been exposed to new functionality for 12 hours that suddenly disappears.

What’s my answer then? My preference is for 10am deployments: our load peaks at night, so 10am is still relatively quiet. The development team is at work and so on hand to look at any issues. But whatever the time of the release I think being able to make a secondary update later in the day is crucial: on a limited budget and weekly releases, the occasional defect will make it onto the site – that I think is simply reality. What I think is important then is to focus on keeping the customer happy by both avoiding peak-time deployments (potential downtime) and avoiding rollbacks (feature loss).

Performance of concurrent XmlReader construction

Hosting FeedZero on a linux server using Mono can be trying at times. Its not that Mono itself is particularly troublesome (I actually think its amazingly good), but more that Mono is red-headed step-child of the wider .NET community – much like those who try and build various command line UNIX tools on Windows.

Usually running .NET assemblies on Mono “just works” but when you encounter a bug – particularly in third party libraries – it seems I am often the first person to have run into it (judging by Google) and so have no real choice except to diagnose it myself.

Worse, many .NET libraries – even open source ones – do not even try to support Mono. Unlike GameCreate, FeedZero utilises a number of third-party libraries and so is more exposed to these sorts of problems. I encountered three separate problems in three separate libraries this week all of which I had to diagnose and either fix or find a work around for.

The most recent issue I encountered was a problem with Argotic which calls itself a “syndication framework” but is more plainly described as a library for parsing RSS feeds. I noticed while inspecting our service logs that with relative regularity, our updates would pause for minutes at a time – often 5 or more. After inspecting a few occurances the common theme was that after each pause an error was displayed due to the RSS feed being invalid in some way.

Armed with the log data, we set about building a test executable that parsed a list of RSS feeds. Running the test against a sample list obtained from the service logs provided the same results as observed in production – provided with a list of 16 feeds 3 of which were invalid, the test would pause for multiple minutes before finally finishing. However running the test executable with a single item list consisting of any one of the three bad RSS feeds did not cause the pausing. Worse, Windows did not seem to have this behaviour.

Due to the number of feeds we need to scan, FeedZero does RSS feed updates in multiple threads at once; the above behaviour was consistent with some sort of concurrency bugs. The three classes of bugs: concurrency-related, third-party library, Mono-only are probably the most tiresome to diagnose and here was an issue that fell into all three categories.

I eventually narrowed my test case down to updating any two invalid RSS feeds at once and still had the pause. For a third party library (and indeed any distinct module of code), the easiest way to to test for a concurrency issue is to simply prevent that module or library from being called by more than one thread at a time. This is very easy to do using C#’s built-in object locking feature:

private static const object _lock = new object();
public void UpdateFeed(string url)
{
    ...
    GenericFeed feed = new GenericFeed();
    lock (_lock)
        feed.Load(url);
    ...
}

Sure enough, with the simple two-line addition of a static object on which to lock the problem went away. Unfortunately for me, FeedZero really needs to get good performance on its feed updating so I would need to identify the underlying cause in Argotic. Through some tedious but necessary analysis I was able to narrow the problem down to the construction of System.Xml.XPath.XPathDocument, a part of the BCL.

My next step was to write a program from scratch that demonstrates the problem, that is not reliant on any other libraries and can be freely distributed. I ended up with a command line executable that created two XPathDocument objects simultaneously with a HTML page as the input, with a command-line argument permitting a lock to be used on the constructor.

This simple program shows the problem; on my PC it took 6 seconds using the lock and over 5 minutes without it. I then turned to Windows, where my first run took 9 seconds without the lock but a subsequent run took almost 2 minutes. Through additional reading, I determined that XPathDocument apparently uses a System.Xml.XmlReader internally and adjusted my test executable to construct XmlReader’s instead; the problem remained.

Finally I altered my executable to perform the test 10 times and report the runtime of each so I could look for average runtime; on both Windows and Linux with the lock I received about 6 seconds – but without the lock, the results are more interesting. While Windows seems to be not too bothered without the lock on the first attempt, on the second attempt it threw some sort of internal timeout exception.

So, both Mono and Windows essentially have very poor performance when attempting to parse two non-XML documents simultaneously; I will package up my test executable and submit a bug to Novell for the mono issue.

So, the final outcome is that I really had no choice but to lock; however a secondary observation from this process is that relying on XmlReader to throw an exception on non-XML takes a pretty long time (multiple seconds); too long for my purposes. Finally I settled on passing the downloaded data through the following regular expression to determine if its likely to be a feed

private static readonly Regex _isFeedRegex = new Regex("<([\\w_-]+:)?(feed|rss|rdf)",
    RegexOptions.IgnoreCase | RegexOptions.Compiled);

If there is no match, then we can skip the entire parsing attempt; with this change we can now fail invalid feeds in a few hundred msec.

Update: Further testing shows that the standard reader obtained from XmlReader.Create notices immediately (on first attempted read) that the document isn’t XML, which makes an even easier way to help out XPathDocument.