Sunday, July 10, 2011

What is a Closure?

This question came up at the last Brighton ALT.NET Beers. It proved almost impossible to discuss in words without seeing some code, so here’s my attempt to explain closures in C#. Wikipedia says:

In computer science, a closure (also lexical closure, function closure or function value) is a function together with a referencing environment for the nonlocal names (free variables) of that function. Such a function is said to be "closed over" its free variables. The referencing environment binds the nonlocal names to the corresponding variables in scope at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure itself.

So a closure is a function that ‘captures’ or ‘closes over’ variables that it references from the scope in which it was created. Yes, hard to picture, but actually much easier to understand when you see some code.

var x = 1;

Action action = () =>
{
var y = 2;
var result = x + y;
Console.Out.WriteLine("result = {0}", result);
};

action();

Here we first define a variable ‘x’ with a value of 1. We then define an anonymous function delegate (a lambda expression) of type Action. Action takes no parameters and returns no result, but if you look at the definition of ‘action’, you can see that ‘x’ is used. It is ‘captured’ or ‘closed over’ and automatically added to action’s environment.

When we execute action it prints out the expected result. Note that the original ‘x’ can be out of scope by the time we execute action and it will still work.

It’s interesting to look at ‘action’ in the debugger. We can see that the C# compiler has created a Target class for us and populated it with x:

closure_in_debugger

Closures (along with higher order functions) are incredibly useful. If you’ve ever done any serious Javascript programming you’ll know that they can be used to replace much of the functionality of object oriented languages like C#. I wrote an example playing with this idea in C# a while back.

As usual, John Skeet covers closures in far more detail. Check this chapter from C# in Depth for more information, including the common pitfalls you can run into.

Tuesday, July 05, 2011

The First Rule of Threading: You Don’t Need Threads!

I’ve recently been introduced to a code base that illustrates a very common threading anti-pattern. Say you’ve got a batch of data that you need to process, but processing each item takes a significant amount of time. Doing each item sequentially means that the entire batch takes an unacceptably long time. A naive approach to solving this problem is to create a new thread to process each item. Something like this:

foreach (var item in batch)
{
var itemToProcess = item;
var thread = new Thread(_ => ProcessItem(itemToProcess));
thread.Start();
}

The problem with this is that each thread takes significant resources to setup and maintain. If there are hundreds of items in the batch we could find ourselves short of memory.

It’s worth considering why ProcessItem takes so long. Most business applications don’t do processor intensive work. If you’re not protein folding, the reason your process is talking a long time is usually because it’s waiting on IO – communicating with the database or web services somewhere, or reading and writing files. Remember, IO operations aren’t somewhat slower than processor bound ones, they are many many orders of magnitude slower. As Gustavo Duarte says in his excellent post What Your Computer Does While You Wait:

Reading from L1 cache is like grabbing a piece of paper from your desk (3 seconds), L2 cache is picking up a book from a nearby shelf (14 seconds), and main system memory is taking a 4-minute walk down the hall to buy a Twix bar. Keeping with the office analogy, waiting for a hard drive seek is like leaving the building to roam the earth for one year and three months.

You don’t need to keep a thread around while you’re waiting for an IO operation to complete. Windows will look after the IO operation for you, so long as you use the correct API. If you are writing these kinds of batch operations, you should always favour asynchronous IO over spawning threads. Most (but not all unfortunately) IO operations in the Base Class Library (BCL) have asynchronous versions based on the Asynchronous Programming Model (APM). So, for example:

string MyIoOperation(string arg)

Would have an equivalent pair of APM methods:

IAsyncResult BeginMyIoOperation(string arg, AsyncCallback callback, object state);
string EndMyIoOperation(IAsyncResult);

You typically ignore the return value from BeginXXX and call the EndXXX inside a delegate you provide for the AsyncCallback:

BeginMyIoOperation("Hello World", asyncResult => 
{
var result = EndMyIoOperation(asyncResult);
}, null);

Your main thread doesn’t block when you call BeginMyIoOperation, so you can run hundreds of them in short order. Eventually your IO operations will complete and the callback you defined will be run on a worker thread in the CLR’s thread pool. Profiling your application will show that only a handful of threads are used while your hundreds of IO operations happily run in parallel. Much nicer!

Of course all this will become much easier with the async features of C# 5, but that’s no excuse not to do the right thing today with the APM.

Wednesday, June 29, 2011

I Don’t Have Time for Unit Tests

I’ve helped several organisations adopt Test Driven Development (TDD). The initial worry that almost everyone has, is that it will hurt productivity. It seems intuitively correct, because of course, the developer has to write the unit tests as well as the production code. However when you actually look at how developers spend their time, actually writing code is a small part of it. Check out this study by Peter Hallam from the Visual Studio team at Microsoft:

http://blogs.msdn.com/b/peterhal/archive/2006/01/04/509302.aspx

According to Peter, developers actually spend their days like this (while not reading Code Rant of course :):

  • Writing new code 5%
  • Modifying existing code 25%
  • Understanding Code 70%

If some technique allowed you to half the modifying/understanding parts of the job by doubling the new-code part, you’d now be taking only ~60% of the time you previously took to deliver a feature, almost doubling your productivity.

TDD is that technique. In my experience the productivity gains come from:

  • Allows safe modifications. If you break something when you modify some code, the unit tests fail.
  • Shortening the iteration cycle between writing/running code. No more need to step through your application to part where your new code gets exercised.
  • Mistakes in your code are shallow and obvious. No more need to step through code in the debugger, wondering which part of your application is broken.
  • Code is self-documenting. The unit tests explicitly show how the author expected the code to be used.
  • Code is decoupled. You can’t do TDD without decoupling. This alone makes the code easier to understand as a unit and much safer to modify.

Note that I’m just talking about feature-delivery productivity here. I haven’t mentioned the huge gains in stability and drop in bug-counts that you also get.

Now I don’t deny that TDD is a fundamentally different way of working that takes time to learn. Undoubtedly productivity may drop while a developer is getting up to speed. But in my experience the argument that a developer doing TDD is slower than a developer who doesn’t do it is simply not true.

Monday, June 27, 2011

RabbitMQ, Subscription, and Bouncing Servers in EasyNetQ

If you are a regular reader of my blog, you’ll know that I’m currently working on a .NET friendly API for RabbitMQ, EasyNetQ. EasyNetQ is opinionated software. It takes away much of the complexity of AMQP and replaces it with a simple interface that relies on the .NET type system for routing messages.

One of the things that I want to remove from the ‘application space’ and push down into the API is all the plumbing for reporting and handling error conditions. One side of this to provide infrastructure to record and handle exceptions thrown by applications that use EasyNetQ. I’ll be covering this in a future post. The other consideration, and the one I want to address in this post, is how EasyNetQ should gracefully handle network connection or server failure.

The Fallacies of Distributed Computing tell us that, no matter how reliable RabbitMQ and the Erlang platform might be, there will still be times when a RabbitMQ server will go away for whatever reason.

One of the challenges of programming against a messaging system as compared with a relational database, is the length of time that the application holds connections open. A typical database connection is opened, some operation is run over it – select, insert, update, etc – and then it’s closed. Messaging system subscriptions, however, require that the client, or subscriber, holds an open connection for the lifetime of the application.

If you simply program against the low level C# AMQP API provided by RabbitHQ to create a simple subscription, you’ll notice that after a RabbitMQ server bounce, the subscription no longer works. This is because the channel you opened to subscribe to the queue, and the consumption loops attached to them, are no longer valid. You need to detect the closed channel and then attempt to rebuild the subscription once the server is available again.

The excellent RabbitMQ in Action by Videla and Williams describes how to do this in chapter 6, ‘Writing code that survives failure’. Here’s their Python code example:

rabbit_mq_in_action_failure_detecting_subscriber

EasyNetQ needs to do something similar, but as a generic solution so that all subscribers automatically get re-subscribed after a server bounce.

Here’s how it works.

Firstly, all subscriptions are created in a closure:

public void Subscribe<T>(string subscriptionId, Action<T> onMessage)
{
if (onMessage == null)
{
throw new ArgumentNullException("onMessage");
}

var typeName = serializeType(typeof(T));
var subscriptionQueue = string.Format("{0}_{1}", subscriptionId, typeName);

Action subscribeAction = () =>
{
var channel = connection.CreateModel();
DeclarePublishExchange(channel, typeName);

var queue = channel.QueueDeclare(
subscriptionQueue, // queue
true, // durable
false, // exclusive
false, // autoDelete
null); // arguments

channel.QueueBind(queue, typeName, typeName);

var consumer = consumerFactory.CreateConsumer(channel,
(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body) =>
{
var message = serializer.BytesToMessage<T>(body);
onMessage(message);
});

channel.BasicConsume(
subscriptionQueue, // queue
true, // noAck
consumer.ConsumerTag, // consumerTag
consumer); // consumer
};

connection.AddSubscriptionAction(subscribeAction);
}

The connection.AddSubscriptionAction(subscribeAction) line passes the closure to a PersistentConnection class that wraps an AMQP connection and provides all the disconnect detection and re-subscription code. Here’s AddSubscriptionAction:

public void AddSubscriptionAction(Action subscriptionAction)
{
if (IsConnected) subscriptionAction();
subscribeActions.Add(subscriptionAction);
}

If there’s an open connection, it runs the subscription straight away. It also stores the subscription closure in a List<Action>.

When the connection gets closed for whatever reason, the AMQP ConnectionShutdown event fires which runs the OnConnectionShutdown method:

void OnConnectionShutdown(IConnection _, ShutdownEventArgs reason)
{
if (disposed) return;
if (Disconnected != null) Disconnected();

Thread.Sleep(100);
TryToConnect();
}

We wait for a little while, and then try to reconnect:

void TryToConnect()
{
ThreadPool.QueueUserWorkItem(state =>
{
while (connection == null || !connection.IsOpen)
{
try
{
connection = connectionFactory.CreateConnection();
connection.ConnectionShutdown += OnConnectionShutdown;

if (Connected != null) Connected();
}
catch (RabbitMQ.Client.Exceptions.BrokerUnreachableException)
{
Thread.Sleep(100);
}
}
foreach (var subscribeAction in subscribeActions)
{
subscribeAction();
}
});
}

This spins up a thread that simply loops trying to connect back to the server. Once the connection is established, it runs all the stored subscribe closures (subscribeActions).

In my tests, this solution has worked very nicely. My clients automatically re-subscribe to the same queues and continue to receive messages. One of the main motivations to writing this post, however, was to try and elicit feedback, so if you’ve used RabbitMQ with .NET, I’d love to hear about your experiences and especially any comments about my code or how you solved this problem.

The EasyNetQ code is up on GitHub. It’s still very early days and is in no way production ready. You have been warned.

Thursday, June 02, 2011

Some Thoughts on Windows 8

Microsoft is the rabbit caught in Apple’s headlights… and about to be run over by the Google juggernaut. Microsoft’s income comes from two major sources, Windows and Office. The need to maintain the stream of licence fees for these two products is at the very core of everything Microsoft does. Windows has three major groups of customers: consumer PCs, business PCs and business servers. Microsoft is the incumbent in all three markets, it can’t grow any more by taking market share, its income can only increase at the rate of growth for these markets as a whole. The only way Microsoft can break out of this static lock is by creating new markets for its products. But it must be careful not to injure it’s existing Windows franchises in attempts to get market share elsewhere.

But it’s a tough world to be selling operating system licences. Unfortunately for Microsoft, the situation is far from static. It’s core source of income is under threat. The iPad has created a new class of consumer product that is eroding Microsoft’s market for consumer PCs. Many people have no need for the full power of a desktop PC. For browsing, reading and writing email and watching YouTube, an iPad, or one of the many Android competitors is perfectly adequate. Android in particular is becoming more and more able to do PC like tasks with every release. For many people a PC is overcomplicated and unreliable.

Windows is also under threat in business server rooms. The main challenge here is from cloud based services. Why employ expensive people to look after servers running Exchange when you can simply sign up for Google Apps? For many small and medium businesses, cloud based services are a very attractive alternative to running in-house IT.

Windows is probably safest of all on the business desktop. There’s no real alternative for running productivity applications like Office. However, with many line-of-business applications becoming cloud based, there is a risk that a Chrome OS style browser-only desktop might look attractive to some business. Also when everyone’s got an iPad or an Android tablet at home, having a similar device at work will start to make more sense.

So is Windows 8 an answer to any of these challenges? It’s obviously designed to answer the first, the erosion of the consumer PC market by iPad and friends. Fundamentally it looks like a simple UI layer, derived from WP7, stuck on top of Windows 7. Microsoft’s strategy seems to be to offer a simple touch-UI for ‘consumer’ tasks, but which allows you to switch back to Windows 7 for running desktop applications like Office. John Gruber makes the point here, that simply skinning Windows 7 for tablets is probably a mistake.

Microsoft is not the leader in the tablet market, it’s playing catch-up from quite a long way behind. Will consumers be willing to pay the Windows tax when they can simply buy a more mature iPad or Android device? Microsoft can’t start offering it for free like Google does with Android because they would immediately kill one of their main sources of income. There is no way they can do anything other than ask people to pay more, for what will, at least initially, be an inferior device. It doesn’t strike me as a winning strategy.

The Windows 8 developer story is somewhat odd to say the least. No mention of WPF or Silverlight. Instead developers are being asked to build apps for the Windows 8 touch UI in Javascript and HTML. There are more Javascript developers out there than Silverlight ones, but the people who already care about Microsoft platforms have put considerable investment into WPF and Silverlight. The Windows 8 announcement is a real slap-down for them. Just take a look at the anger on Channel 9. It’s also a snub to Microsoft’s developer division who have put considerable effort into building .NET. Is this a hangover from the Vista debacle? Was WinFX such a failure that the Windows team now want nothing to do with .NET? If so, what’s the point of the developer division?

It’s a confusing time for us developers. I think Microsoft still have a very strong position on the business desktop. If you are building line-of-business applications for a living with .NET, there’s probably still some millage in that. But the feeling is very much that .NET is now middle age, like many of its developers. No matter how nice the technology is, and it is very nice, it’s part of a platform that’s perceived to be part of the past, not the future.

But if you are building for the consumer market, or the cloud, then Microsoft is merely a niche player. It’s been obvious for some time that everyone should have Javascript as a core skill. The Windows 8 announcement reinforces that. It’s also clear that UNIX/Linux operating systems (including iOS and Android) are now ubiquitous in the same way that TCP/IP is. You’d probably want to make sure you know how to find your way around a UNIX system. For building server side applications for the cloud the field is wide open. Ruby, Python & Javascript are all well established and for some exotic applications, things like Erlang, Scala and Haskell are very interesting. Personally I’m hoping, optimistically I think, that Mono and Xamarin are a success. The excellent .NET platform deserves more than to be chained to Windows’ declining market share.

Monday, May 30, 2011

Dependency Injection Haskell Style

Today I was thinking about dependency injection and Haskell. If we think about how an IoC container in a language like C# works, there are several pieces:

  1. Services are described by types (usually interfaces).
  2. Components (classes) describe their dependencies with the types of their constructor arguments.
  3. The components in turn describe the services they provide by implementing service interfaces.
  4. Service types are registered against implementation types using some API provided by the IoC container.
  5. A clever piece of framework (the IoC container), that when asked for a service (described by an interface), creates the entire dependency chain and then passes it the caller.

The important point is that we don’t have to manually wire up the dependency chain. We simply build our software in terms of service contracts and implementations, register them with the IoC container which then magically does the wiring up for us.

If you dig into the source code for any of the .NET IoC containers (such as Windsor, StructureMap, Autofac, Ninject etc) you’ll see they do an awful lot of reflection to work out the dependency graph. I remember reading (or hearing someone say) that reflection is often used to make up for inadequacies in C#’s type system, so I started experimenting to see if Haskell could provide the decoupling of registration and dependency graph building without the need for an IoC container. And indeed it can.

First let’s define some services:

-- this could talk to a database
type GetReport = Int -> IO Report
-- this could talk to an email API
type SendReport = Report -> IO ()
-- this takes a report id and does something with it
type ProcessReport = Int -> IO ()

Now let’s define some implementations:

-- getReport simply creates a new report with the given id
getReport :: GetReport
getReport id =
return $ Report id "Hello"

-- sendReport simply prints the report
sendReport :: SendReport
sendReport report = putStr $ show report

-- processReport uses a GetReport and a SendReport to process a report
processReport :: GetReport -> SendReport -> ProcessReport
processReport get send id = do
r <- get id
send r

Partial function application is equivalent to dependency injection in OO. Here our processReport’s dependencies are given as the first two arguments of the processReport function.

Now let’s define a type class with a ‘resolve’ member. The resolve member isn’t a function as such, it’s just a label for whatever ‘a’ happens to be when we define instances of the type class:

class Resolvable a where
resolve :: a

Now let’s make each of our services an instance of ‘Resolvable’, and ‘register’ the implementation for each service:

instance Resolvable GetReport where
resolve = getReport

instance Resolvable SendReport where
resolve = sendReport

instance Resolvable ProcessReport where
resolve = processReport resolve resolve

Note that we partially apply processReport with two resolve calls that will provide implementations of the service types.

The whole caboodle compiles and we can use resolve to grab a ProcessReport implementation with its dependencies provided:

> let p = resolve :: ProcessReport
> p 23
Report 23 "Hello"

All the functionality of an IoC container without an IoC container. Wonderful.

So, to sum up, we’ve simply registered implementations against services and let the Haskell type system build the dependency graph for us. The added benefit we get here over reflection based IoC containers in C# and Java, is that this is all typed checked at compile time. No need to run it to find missing dependencies.

Please bear in mind that I’m a total Haskell novice and this is probably something that real Haskell programmers would never do. But it’s an interesting illustration of the power of the Haskell type system, and how a lot of what we do with reflection in C# is simply to augment the limitations of the language.

Thursday, May 19, 2011

FuturePublish with the EasyNetQ RabbitMQ API

If you’re a regular reader, you’ll remember that I published an initial version EasyNetQ, my .NET friendly API for RabbitMQ, earlier this month. Today I want to show off a little addition that allows messages to be scheduled for publishing at a future date.

Many business scenarios require some kind of scheduling. For example, say I want to send a party invitation, but I know that it will be forgotten if I send it too early. Instead I want it to arrive two days before the party. I’d like to ‘future publish’ my invite at the time I’m planning my party, and let the messaging system worry about sending it two days before hand.

I’ve added a FuturePublish method to the EasyNetQ, you simply give it a messasge and the time that you want it sent.

var invitation = new PartyInvitation
{
Text = "Please come to my party",
Date = new DateTime(2011, 5, 24)
};

bus.FuturePublish(invitation.Date.AddDays(-2), invitation);

That’s cool, how does it work?

Internally the FuturePublish method wraps the given message in a special ‘Schedule Me’ message. This message is then published to Rabbit as normal. A windows service, EasyNetQ.Scheduler, subscribes to the Schedule Me messages which it writes to its database. At a pre-defined interval, it polls its database looking for messages who’s publish date is the current time, retrieves the wrapped message and publishes it.

Check out the source on GitHub here:

https://github.com/mikehadlow/EasyNetQ

Wednesday, May 04, 2011

EasyNetQ, a simple .NET API for RabbitMQ

After pondering the results of our message queue shootout, we decided to run with Rabbit MQ. Rabbit ticks all of the boxes, it’s supported (by Spring Source and then VMware ultimately), scales and has the features and performance we need. The RabbitMQ.Client provided by Spring Source is a thin wrapper that quite faithfully exposes the AMQP protocol, so it expects messages as byte arrays.

For the shootout tests spraying byte arrays around was fine, but in the real world, we want our messages to be .NET types. I also wanted to provide developers with a very simple API that abstracted away the Exchange/Binding/Queue model of AMQP and instead provides a simple publish/subscribe and request/response model. My inspiration was the excellent work done by Dru Sellers and Chris Patterson with MassTransit (the new V2.0 beta is just out).

The code is on GitHub here:

https://github.com/mikehadlow/EasyNetQ

The API centres around an IBus interface that looks like this:

/// <summary>
/// Provides a simple Publish/Subscribe and Request/Response API for a message bus.
/// </summary>
public interface IBus : IDisposable
{
/// <summary>
/// Publishes a message.
/// </summary>
/// <typeparam name="T">The message type</typeparam>
/// <param name="message">The message to publish</param>
void Publish<T>(T message);

/// <summary>
/// Subscribes to a stream of messages that match a .NET type.
/// </summary>
/// <typeparam name="T">The type to subscribe to</typeparam>
/// <param name="subscriptionId">
/// A unique identifier for the subscription. Two subscriptions with the same subscriptionId
/// and type will get messages delivered in turn. This is useful if you want multiple subscribers
/// to load balance a subscription in a round-robin fashion.
/// </param>
/// <param name="onMessage">
/// The action to run when a message arrives.
/// </param>
void Subscribe<T>(string subscriptionId, Action<T> onMessage);

/// <summary>
/// Makes an RPC style asynchronous request.
/// </summary>
/// <typeparam name="TRequest">The request type.</typeparam>
/// <typeparam name="TResponse">The response type.</typeparam>
/// <param name="request">The request message.</param>
/// <param name="onResponse">The action to run when the response is received.</param>
void Request<TRequest, TResponse>(TRequest request, Action<TResponse> onResponse);

/// <summary>
/// Responds to an RPC request.
/// </summary>
/// <typeparam name="TRequest">The request type.</typeparam>
/// <typeparam name="TResponse">The response type.</typeparam>
/// <param name="responder">
/// A function to run when the request is received. It should return the response.
/// </param>
void Respond<TRequest, TResponse>(Func<TRequest, TResponse> responder);
}

To create a bus, just use a RabbitHutch, sorry I couldn’t resist it :)

var bus = RabbitHutch.CreateRabbitBus("localhost");

You can just pass in the name of the server to use the default Rabbit virtual host ‘/’, or you can specify a named virtual host like this:

var bus = RabbitHutch.CreateRabbitBus("localhost/myVirtualHost");

The first messaging pattern I wanted to support was publish/subscribe. Once you’ve got a bus instance, you can publish a message like this:

var message = new MyMessage {Text = "Hello!"};
bus.Publish(message);

This publishes the message to an exchange named by the message type.

You subscribe to a message like this:

bus.Subscribe<MyMessage>("test", message => Console.WriteLine(message.Text));

This creates a queue named ‘test_<message type>’ and binds it to the message type’s exchange. When a message is received it is passed to the Action<T> delegate.  If there are more than one subscribers to the same message type named ‘test’, Rabbit will hand out the messages in a round-robin fashion, so you get simple load balancing out of the box. Subscribers to the same message type, but with different names will each get a copy of the message, as you’d expect.

The second messaging pattern is an asynchronous RPC. You can call a remote service like this:

var request = new TestRequestMessage {Text = "Hello from the client! "};

bus.Request<TestRequestMessage, TestResponseMessage>(request, response =>
Console.WriteLine("Got response: '{0}'", response.Text));

This first creates a new temporary queue for the TestResponseMessage. It then publishes the TestRequestMessage with a return address to the temporary queue. When the TestResponseMessage is received, it passes it to the Action<T> delegate. RabbitMQ happily creates temporary queues and provides a return address header, so this was very easy to implement.

To write an RPC server. Simple use the Respond method like this:

bus.Respond<TestRequestMessage, TestResponseMessage>(request => 
new TestResponseMessage { Text = request.Text + " all done!" });

This creates a subscription for the TestRequestMessage. When a message is received, the Func<TRequest, TResponse> delegate is passed the request and returns the response. The response message is then published to the temporary client queue.

Once again, scaling RPC servers is simply a question of running up new instances. Rabbit will automatically distribute messages to them.

The features of AMQP (and Rabbit) make creating this kind of API a breeze. Check it out and let me know what you think.

Wednesday, April 13, 2011

Serializing Continuations

Continuations are cool. They allow you to write some code that uses the enclosing state, but which can be executed in some other context at some other time. What if we could serialize the continuation and put it away in a database, a file, or even a message on a service bus only to be grabbed later and then executed? Well we can.

Take a look at this code:

private const string filePath = @"C:\temp\serialized.action";

public static void BuryIt()
{
const string message = "Hello!";

var bytes = DoSomethingLater(name => Console.WriteLine(message + " " + name));

using(var stream = File.Create(filePath))
{
stream.Write(bytes, 0, bytes.Length);
}
}

public static void ResurrectIt()
{
var bytes = File.ReadAllBytes(filePath);
ExecuteSerializedAction("Mike", bytes);
}

public static byte[] DoSomethingLater(Action<string> action)
{
var formatter = new BinaryFormatter();
var stream = new MemoryStream();

formatter.Serialize(stream, action);
stream.Position = 0;
return stream.GetBuffer();
}

public static void ExecuteSerializedAction(string name, byte[] serializedAction)
{
var formatter = new BinaryFormatter();
var stream = new MemoryStream(serializedAction);
var action = (Action<string>)formatter.Deserialize(stream);

action(name);
}

In ‘BuryIt’ we call DoSomethingLater passing to it a continuation that includes some of TryIt’s state, namely the message string “Hello!”. DoSomethingLater takes takes the ‘action’ delegate, serializes it and returns the serialized bytes to its caller. BuryIt then writes the bytes to a file.

Next we execute ResurrectIt. It opens the file, reads the bytes and  hands them to ExecuteSerializedAction. This de-serializes the byte array back to an Action<string> and then executes it with the name parameter. When you execute it, it prints out:

Hello! Mike

This is very cool. Say we had some long running process where we wanted to execute each continuation at an interval  and have the process go away in between each execution. We could use this technique to store the state at each stage in a database and have each instance carry on where the previous one left off.

Sunday, April 10, 2011

Message Queue Shootout!

I’ve spent an interesting week evaluating various Message Queue products. The motivation behind this is a client that has somewhat high performance requirements. They have bursts of over a million simultaneous messages. Currently they’re using a SQL server based solution, but it’s not ideal, and I’m suggesting they look at Message Queuing products as an alternative.

In order to get a completely unscientific feel for the performance of some likely contenders, I put together a little test. Each queue would be asked to send one million 1K messages and receive them again. The test was done in somewhat of a hurry, so I haven’t tweaked any settings, just installed each MQ and done the simplest send and receive I could manage after a quick glance at the docs. So this is true out-of-the-box performance. I fully accept that this is going to penalise MQ products that have conservative default configurations.

The candidates are:

  • MSMQ. The default choice for where only the products of Redmond are considered worthy. For my clients, if MSMQ can rise to the challenge, then they should use it. The main points against it are its lack of sophistication; nothing but send and receive; and it’s arbitrary hard limits, such as the 4MB maximum message size. However, with something like MassTransit or NServiceBus layered on top, it’s entirely possible to do serious work with it.
  • ActiveMQ. The stalwart of the Java world. It has long service and ubiquity going for it. It’s also cross platform and would provide a natural integration point for non-Microsoft platform products. However, it would have to perform better than MSMQ to have a look-in.
  • RabbitMQ. I’ve been hearing excellent things about this message broker written in Erlang. It supports the open AMQP (Advanced Message Queuing Protocol) with the potential to avoid vendor lock-in and benefiting from a wide range of clients in almost every language. AMQP provides some pretty sophisticated messaging patterns, so there’s less need for a MassTransit or NServiceBus. It also has ‘enterprise’ resilience and durability. That’s something my client is very interested in.
  • ZeroMQ. I only discovered this MQ product when I was researching AMQP. The company that created it were part of the AMQP group and had a product called OpenAMQ. However, they parted company with AMQP quite dramatically, complaining that it had lost its way and was becoming over complicated. You can read their Dear John letter here. ZeroMQ has a unique broker-less model which means that unlike all the other products under test, you don’t need to install and run a message queuing server, or broker. Simply reference the ZeroMQ library, it’s on NuGet, and you can happily send messages between your applications. Interestingly, they are also placing it as a way of creating Erlang style actors in any language by leveraging ZeroMQ’s blazingly fast in-process messaging.

Getting all four MQ products up and running was fun. There’s a definite overhead when you have to install a product based on a non-Windows platform. ActiveMQ required Java on the target machine and RabbitMQ needed Erlang. Both installed without a hitch, but I’m concerned that it’s another layer that can go wrong in production. I would be asking the infrastructure people to understand and maintain unfamiliar runtimes if we chose either of these. ActiveMQ, RabbitMQ and MSMQ all have server processes that need to be monitored and configured, another support concern.

ZeroMQ, with its brokerless architecture doesn’t require any server process or runtime. In effect, your application endpoints play the server role. This makes deployment simpler, but the worry is that there’s no obvious place to go looking when things go wrong. ZeroMQ, as far as I can tell, only provides non-durable queues. You are expected to provide your own auditing and recovery where you need it. To be honest, I’m not even sure that ZeroMQ should be in this test, it’s such a different concept than the other MQ products.

So without further chit-chat, here are the results. This is messages per second, for send and receive. During the transmission of one million 1K messages. The tests were executed a machine running Windows Vista.

mqshootout

As you can see, there’s ZeroMQ and the others. Its performance is staggering. To be fair, ZeroMQ is quite a different beast from the others, but even so, the results are clear: if you want one application to send messages to another as quickly as possible, you need ZeroMQ. This is especially true if you don’t particularly mind loosing the occasional message.

To be honest, I was hoping for more from Rabbit. However much one tries to be fair in these things, you inevitably have a favourite, and everything I’d read and heard about Rabbit made me think it was probably the best choice. But with these results, I’m going to be hard pressed to sell it over MSMQ.

If you’d like to run the tests for yourself, my test code is on GitHub here. I’d be very (no very very) interested in how the tests can be tweaked, so if you can get substantially better figures, please let me know.

https://github.com/mikehadlow/Mike.MQShootout