Optimising an ASP.NET MVC web site part 1 – Introduction
Note: This was originally posted on my old blog at the EMC Consulting Blogs site.
One of the things I’ve been involved in over the past couple of months is performance tuning work for my current project (now live at www.fancydressoutfitters.co.uk). One of my EMC Consulting colleagues, Marcin Kaluza, has recently started posting on this subject and I’ve been encouraged by Howard to post some “war stories” of the kind of things I’ve encountered whilst doing this on projects, starting with the most recent.
So first, some background. It’s an public facing website project, and is based on Billy McCafferty’s excellent S#arp Architecture – which means it’s ASP.NET MVC with NHibernate talking to SQL Server 2008 databases. We’re using the Spark View Engine instead of the out of the box one, and the site uses N2 CMS to provide content management capabilities (James posted a while back on the reasons for choosing N2.) Finally, we use Solr to provide our search functionality, integrated using Solrnet. I joined the team a few months into the project, by which point they had laid a firm foundation and were about to be abandoned for 6 weeks by their technical lead who had inconsiderately booked his wedding and an extended honeymoon right in the middle of the project.
When the project was set up it was done so in strictly in accordance with agile principles. A small team was given a fixed date for go-live and the directive to spend the client’s money as if it were their own. One of the first things that happened was the adoption of a number of principles from the excellent 37signals e-book “Getting Real”. A product backlog was assembled, and then – in accordance with the “build less” maxim – divided into “core” and “non-core” user stories. The core stories were what was essential for go live – things the client couldn’t live without, such as basic search and content management. The non-core stories are things that might enhance the site but aren’t essential – for example, advanced search features such as faceted navigation.
The absolute focus the team maintained on the core functionality and target delivery date has made this one of the best and most successful agile projects I’ve worked on – we reached our go live date on budget and were able to substantially over deliver on functionality. Whilst the site is relatively basic compared to some I’ve worked on, it stands out amongst its peers and provides a great platform for new functionality to be built on.
However, now I’ve extolled the virtues of the approach that was taken, I should talk about the performance optimisation and testing work we did. Since I have some experience from previous projects, I took on the task of testing the site to make sure it could handle an acceptable level of load without falling over in an embarrassing heap. However, before I started on that, we did some optimisation work on the site.
The aim was to hit the major pain points, since we knew performance had degraded over the previous few sprints. Once this was done, we could run some load testing and perform further tuning and optimisation work as required. I was originally intending to write a single post covering the optimisation process, then follow that up with one about the load testing process. However, that resulted in a rather lengthy post, so I’m splitting it up into several parts that I will post over the next week or two:
- Part 1: Introduction (this post)
- Part 2: Database and NHibernate-based repositories
- Part 3: Application caching
- Part 4: View optimisation and output caching
- Part 5: Putting your money where your mouth is
In addition, I’ve already covered the work we did to correctly configure IIS in my post How to improve your YSlow score under IIS7.
I hope you find these posts interesting – please let me know what you think by leaving a comment.
Add Timeouts to your methods with PostSharp
Note: This was originally posted on my old blog at the EMC Consulting Blogs site.
In my previous post, “Make methods fire and forget with PostSharp”, I showed how a PostSharp aspect could be used to stop non-critical methods from blocking execution. Staying on a similar theme, in this post I will show how you can use the AOP framework to add timeouts to methods.
In one of my current projects, we’re using Microsoft Velocity CTP3. Whilst this is proving to be pretty good, it has an annoying tendancy to take the entire site down with it if it blows up. We therefore added some code to allow the site to keep running if the cache stops working so that the problem could be rectified without causing more than a slowdown. This code worked perfectly, but I hit the minor snag that Velocity operations like DataCacheFactory.GetCache appear to have something like a 10 second timeout. Our app will typically make tens of calls to the cache to generate a single page so whilst I stopped the site crashing, it was still unusable.
I couldn’t find a way to lower the timeout in Velocity, so I had to implement it in my own methods. The standard code for adding a 1 second timeout in a method would look something like this:
- public class TimeoutWithoutPostsharp
- {
- public object MyMethod(object param)
- {
- var methodDelegate = new Func<object, object>(this.MyMethodInner);
- var result = methodDelegate.BeginInvoke(
- param,
- null,
- null);
- if (!result.AsyncWaitHandle.WaitOne(1000))
- {
- throw new TimeoutException();
- }
- return methodDelegate.EndInvoke(result);
- }
- private object MyMethodInner(object param)
- {
- // Do the work
- }
- \
We create a delegate to the method proper, which we can then invoke using BeginInvoke() on the delegate. This returns an IAsyncResult, from which we can use the AsyncWaitHandle to wait for the method to complete. The WaitOne method allows us to specify the timeout interval we want, and returns true if the method completes within that period. If it doesn’t, we raise a TimeoutException, otherwise we call EndInvoke() on the delegate and return the correct value.
If you read my previous post you’ll know what to expect with PostSharp in play…
- public class TimeoutWithPostSharp
- {
- [Timeout(1000)]
- public object MyMethod(object param)
- {
- // Do the work
- }
- }
Again, all the plumbing is eliminated and you end up with clean code in which it’s obvious what’s going on. As with the Asynchronous attribute, this is implemented by inheriting the PostSharp.Laos.OnMethodInvocationAspect base class, which replaces the original method with a generated one that calls into your attribute. The code is straightforward, following the pattern shown in the first code snippet:
- [Serializable]
- public class TimeoutAttribute : OnMethodInvocationAspect
- {
- /// <summary>
- /// Initializes a new instance of the <see cref=”TimeoutAttribute”/> class.
- /// </summary>
- /// <param name=”timeoutMs”>
- /// The timeout period in ms.
- /// </param>
- public TimeoutAttribute(int timeoutMs)
- {
- this.TimeoutMs = timeoutMs;
- }
- /// <summary>
- /// The timeout period in ms.
- /// </summary>
- public int TimeoutMs { get; set; }
- public override void OnInvocation(MethodInvocationEventArgs eventArgs)
- {
- Action proceedAction = eventArgs.Proceed;
- IAsyncResult result = proceedAction.BeginInvoke(
- null,
- null);
- bool completed = result.AsyncWaitHandle.WaitOne(this.TimeoutMs);
- if (!completed)
- {
- throw new TimeoutException();
- }
- proceedAction.EndInvoke(result);
- }
- }
The code for this aspect, along with some unit tests to prove I’m not making all this up, can be downloaded from Codeplex.

2 comments