We’ve spent the last few weeks porting the Aeron client from Java to .NET.

What is Aeron?

Aeron is a high speed message transport. It allows messages to be sent over the network via UDP (unicast or multicast) or between processes via IPC in shared memory.

Aeron is the brainchild of Martin Thompson and Todd Montgomery. Martin was the co-founder and CTO of LMAX and is a high-performance specialist. Todd was CTO of 29West where he was the chief designer of their low latency messaging products. They’ve been working on Aeron over the past 2 years and have just released version 1.0.

It is made up of clients and a media driver. The clients encode/decode messages and pass them to the media driver which runs in its own process and is responsible for sending and received messages over the network. The clients communicate with the media driver through shared memory using lock-free algorithms.


Aeron Overview

As well as the C# client, there are also clients written in Java and C++.

Show me some numbers

At the time of writing, when using C# Aeron client and the Java media driver, it is capable of sending and receiving about 30 million messages per second. We used HDRHistogram.Net to measure latency by measuring the roundtrip time of a message. 99% of messages roundtrips are under 25 microseconds. You can check these numbers yourself by running the media driver with the IpcThroughput sample and the Ping and Pong samples.

latency histogram

Once it’s up and running, it does not allocate any memory which means that latency is more predictable because no time is spent garbage collecting.

Show me some code

There is a full Hello World example here. Here’s a breakdown of the most important parts.

Publisher

The client connects to the media driver and instructs it to prepare a publisher which will send messages to another media driver listening on UDP port 40123. Messages can be split into different streams and sent to the same channel.

Creating a message

Part of the reason Aeron is able to achieve such high throughput is by not creating objects when sending messages. Instead of newing up a DTO, Aeron uses byte arrays to represent messages. UnsafeBuffer is a wrapper that has methods for writing various types.

Sending a message

To send the message, just pass the message buffer along with the offset at which the message starts and the length of the message to the publisher.

Subscriber

The next code fragment sets up a subscription, it causes the media driver to listen on the endpoint defined by channel, in this case udp://localhost:40123 and pick up messages sent to the relevant streamId. You pass it a message handler (which will be explained in the next section) and a fragment limit which defines the maximum number of fragments to process in one poll.

Processing a message

The FragmentHandler defines what happens to messages that are received by a subscription. In this case, we know the message consists of a string so we can read it out directly. For more complex scenarios, for instance when messages might be too large and need to be split up, a FragmentAssembler can be used to reassemble the message.

Where can I get it?

The Aeron client is available from NuGet.

Alternatively, the source code is up on GitHub:

https://github.com/AdaptiveConsulting/Aeron.NET/

You can also get a copy of the Java driver through NuGet:

What’s Next?

We will continue to work on the code keeping it up to date with changes to the official Java version, fixing bugs and improving performance where we can. We need early adopters to pick up the code and start playing around.