Kevin Kallberg

The life and times of a software developer


Achieving Delayed Messaging in ServiceStack with RabbitMQ and EasyNetQ


Recently I was looking for a good, durable way to schedule web events for a project at work.  The project requires high throughput, so I needed a fast, scalable solution for persisting these events.  As fortune would have it, about a month before the project began, a new plugin was announced for RabbitMQ that supported delayed messaging.  A message queue seemed like it might be a good fit for the project needs, so I decided to take a look at it.

Picking the pieces

At work, we use (the fantastic) ServiceStack web service framework.  We’ve used RabbitMQ in the past, and the plugin for ServiceStack makes it very easy to publish and consume messages.  However, ServiceStack’s RabbitMQ plugin is very opinionated and does not leave a lot of room for customization without going down to the RabbitMQ.Client library itself.  I wanted something that would allow me to retain a lot of the simplicity that the ServiceStack RabbitMQ plugin offers but provide further points of configuration.

Enter, EasyNetQ

EasyNetQ_LogoEasyNetQ is an open source client API for RabbitMQ on .NET.  It has over 100,000 downloads on and over 1,200 commits across 70+ contributors on GitHub.  Not only does the health of the project look great, but EasyNetQ also comes with a feature that I was specifically looking for: scheduling messages.  EasyNetQ has long supported scheduled messages through the use of a companion Windows service.  However, as of late April, 2015, support for the new delayed exchange plugin for RabbitMQ was added.

Putting it all together

Now that the pieces have been assembled, it is time to tie them all together.  The project is simple.  It consists of only a pair of services with a single operation each, a pair of POCOs and the AppHost, which initializes ServiceStack and the other components.

The Message

With RabbitMQ, we can simply create a POCO to push into a message queue.  For our sample, our POCO contains just two DateTime properties.  The Queue attribute comes courtesy of EasyNetQ and allows us to specify the name of the queue and exchange that are created in RabbitMQ.

[Queue("DelayedMessageSampleQueue", ExchangeName = "DelayedMessageSampleExchange")]
public class DelayedMessage
    public DateTime PublishTime { get; set; }
    public DateTime SentTime { get; set; }

The Services

The project contains two services: one to publish messages and one to consume them.  The PublishService is a simple ServiceStack service that responds at /publish.  A single parameter, MillisecondsDelay, can be specified on either the query string or in the post body.  A new DelayedMessage will be created and the PublishTime set.  The service will then get a reference to EasyNetQ’s IBus interface from ServiceStack’s IoC container and use it to publish the message.  Note the use of the FuturePublish method.

public class PublishRequest : IReturnVoid
    public double MillisecondDelay { get; set; }

public class PublishService : Service
    public void Any(PublishRequest request)
        var message = new DelayedMessage { PublishTime = DateTime.UtcNow };

        var bus = HostContext.Container.Resolve<IBus>();
        bus.FuturePublish(TimeSpan.FromMilliseconds(request.MillisecondDelay), message);

The DelayedMessageService is responsible for consuming the message queue when the message delay is reached.  The service sets the SentTime property on the message and then writes a message to the Debug output.

public class DelayedMessageService : Service
    // This is the queue consumer for the DelayedMessage queue.
    public void Any(DelayedMessage message)
        message.SentTime = DateTime.UtcNow;

        Debug.WriteLine("{0}New Message Recieved!{0}\tPublished: {1}{0}\tSent: {2}{0}", 

The AppHost

ServiceStack’s AppHost is where initialization of the message queue takes place.  EasyNetQ is registered using its static RabbitHutch.CreateBus method.  Note the registration of the IScheduler interface with a DelayedExchangeScheduler.  This is where we tell EasyNetQ to engage the RabbitMQ delayed exchange plugin.  Next, we configure the message queue to deliver our delayed messages to the DelayedMessageService we looked at above.  To do so, we use the IBus interface’s Subscribe method.  We pass an empty string as the subscriptionId parameter (since we’re using the Queue attribute mentioned previously) and an anonymous method for the callback.  When a delayed message is ready to be sent it is dequeued and enters the Subscribe callback.  Here, we convert the POCO message to an IMessage<T> and pass it to ServiceStack's ServiceController.ExecuteMessage method which delivers it to our service.

public class AppHost : AppHostBase
    ... snip ...

    /// <summary>
    /// Application specific configuration
    /// This method should initialize any IoC resources utilized by your web service classes.
    /// </summary>
    /// <param name="container"></param>
    public override void Configure(Container container)
        var connectionConfig = new ConnectionConfiguration
            AMQPConnectionString = new Uri("amqp://localhost:5672/"),
            UserName = "guest",
            Password = "guest"
            x => x.Register<IScheduler, DelayedExchangeScheduler>()));

        var bus = container.Resolve<IBus>();
        bus.Subscribe<DelayedMessage>(String.Empty, msg =>
            var message = new ServiceStack.Messaging.Message<DelayedMessage>(msg);


We round out the AppHost by registering our two services.


There are a couple things to keep in mind when using this solution.

  • Requires RabbitMQ Server 3.4 or higher
  • Requires new delayed exchange plugin

Wrapping up

With this new plugin for RabbitMQ and the slick implementation offered by EasyNetQ, it is very straightforward to achieve delayed messaging in ServiceStack.  With just a little bit of configuration you tie right in to the existing infrastructure.  The sample code can be viewed / downloaded in its entirety on GitHub

MacBook Cookout 2014

imageA few years ago, I came into possession of a MacBook Pro (Model A1261).  The machine had had an unfortunate meeting with an open bottle of Mountain Dew and was diagnosed by the Apple Geniuses as suffering from a faulty logic board.  Unfortunately, it was out of warranty.  With its condition confirmed by the powers that be, it was given to me and I quickly relegated it to the closet where it was slowly forgotten.

Fast forward to the second half of 2013.  I had begun to explore Xamarin as a cross-platform development solution.  With Xamarin, you need to have Mac OS X in order to build code for iOS applications (due to Apple restrictions).  This fact reminded me of the Macbook Pro slumbering in my closet and I began scouring the Internet for information on if, and how, I might be able to revive it.  After reading about people having to purchase new logic boards I stumbled across Russell Heistuman's blog post entitled Cooking the Books (or, Baking My MacBook Pro Logic Board).  After reading a myriad of comments from others regaling their own tales of success I decided I had nothing to lose.

Surveying the Scene

I removed the battery from the machine and plugged in the MagSafe power adapter.  To my surprise, the LED on the plug lit up green.  This told me that the power supply in the machine was alive.  I opened the lid and hit the power button.  The LED sleep indicator on the front of the machine illuminated solid white, I could hear the optical drive and hard drive whir to life, the fans spin up, and not much else.  There was no startup chime and more discouraging than that, there was no video on the screen.  I tried a few things including resetting the SMC, hooking up an external monitor, resetting the PRAM, and several different startup keyboard shortcuts.  None of these activities yielded a different startup story and so I started pre-heating the oven and set about dismantling my MacBook Pro.

Journey to the Center of the System

If you’ve never dismantled a MacBook of any kind you will quickly find out that there are a ton of screws between you and the guts of your machine.  To help guide you on your journey to the center of the system, I recommend you check out Powerbook Medic’s great disassembly videos.  These videos will show you exactly how to disassemble your MacBook so you can get at the parts you need.

imageMy initial plan was to pull the logic board from the machine and see if I could clean up any mess present from the Mountain Dew with some 91% isopropyl alcohol.  However, once I removed the logic board, I saw no trace of liquid damage.  There was no visible corrosion of any kind that I could find anywhere on the board.  As luck would have it, it seemed that the keyboard protected the guts from the vast majority of the spill.  There was a little bit of sticky something on the SuperDrive, but aside from that it all looked good.  So, I set about removing the old thermal paste from the chips on the board.  Once it was all removed it was time to transplant it to the kitchen.  I covered a cookie sheet in aluminum foil and made four similarly sized balls of foil to serve the purpose of keeping the logic board from having any direct contact with the cookie sheet itself.  I perched the board on top of the foil balls and was ready to go.

There and Back Again

The oven had been pre-heated to 375° F and I set the oven timer for seven minutes and thirty seconds (7:30).  Once I placed the cookie sheet / logic board combo in the oven I returned to the MacBook shell and worked on removing the old thermal paste from the heatsink.  Once the timer went off I removed the board from the oven and allowed it to cool outside the oven for about fifteen minutes.  I re-applied thermal paste to the chips and mounted the board back into the machine.  To my surprise, when I pressed the power button I was greeted with the same startup story I had before baking, but with one extra ingredient.  The familiar startup chime.  However, there was still no video. 

imageI read a few more comments in Russell’s blog post and some people seemed to have better success at slightly higher temperatures.  I decided to cook my board a second time.  This time I pre-heated the oven to 390° F, cleaned off the thermal paste I had just applied and cooked it again for seven and a half minutes.  After another fifteen minute cooldown I hooked the board back up in the case (this time without bothering with thermal paste for this first try) and pressed the power button.  And once again, my startup story changed, but this time to include video!  The screen lit up beautifully as the startup chime rang out and I was filled with hope for this machine.

All’s Well that Ends Well

I removed the logic board one more time in order to properly apply some more thermal paste and put the machine back together.  After re-installing OS X, the machine is back to its former glory and does a great job acting as a build host for my efforts with Xamarin.  There’s no telling how much longevity I’ll get from the machine, but others have stated that their machines have lasted many months after their baking endeavors.  I suppose only time will tell.


Disclaimer:  The contents of this post are my own experience.  I take no responsibility for any damages you may sustain in attempting to emulate my own activity.  This blog post is for informational purposes only.

Xamarin.iOS Error: “Failed to obtain information about the remote's profile files. Unable to check SDK status.”

icon7-152I had been running into this issue the past few days.  I was using Visual Studio 2013 Professional and an iMac running Mavericks as my build host on the network.  I was able to open Xamarin.iOS projects in Visual Studio, but as soon as I tried to execute it I would get this error.  Google suggested that I make sure that both the Windows and Mac machines had been updated and that the product versions match on both sides.  After checking and re-checking this I was about to give up and try to reinstall when I stumbled onto the answer.

In a post on the Xamarin forums, Brendan Zagaeski of Team Xamarin provided the information that would be the missing piece to my puzzle.  His comment was in response to a different issue that a user was experiencing, but the part in bold was the key bit of information I needed.

…please try updating the clocks on both your Windows and Mac computer to the current accurate internet time. Part of security algorithm for the server-client communication requires that the clocks on both computers have closely matching times.

As expected, my Windows machine was synced with Internet time server and the iMac was synced to  For whatever reason, there was an 8 minute discrepancy between the times on the machines, which was apparently enough for the security algorithm to fail. 

imageIn order to prevent this issue from occurring again in the future I have set my Windows machine to synchronize with the same Internet time server as the iMac.  Once updated and the clocks on both machines were in sync I was able to update the SDK on my Windows machine, allowing me to once again execute Xamarin.iOS applications from Visual Studio.