Trying out NServiceBus part 3: pushing an event

In previous posts I’ve shown how I’ve setup testing environment for trying out NServiceBus. After dealing with some problems applications started to work correctly, at least to some extent. The only problem left is that event is being published, but it does not always reach the handler. Why is that?

I’ve setup my solution to start both Mailer and nServiceBusFun projects when I hit F5 (you can do it by right clicking on solution and selecting “Set StartUp projects…”). And sometimes when I do that message is being sent from publisher and is being delivered to handler correctly, but sometimes it’s not. The reason for this is we have here a race condition. Simply – if Mailer fails to register before nServiceBusFun publishes the event, it is not being delivered, which is pretty natural – NServiceBus cannot hold every possible event published and push it to handlers in future after they register. So I modified my publisher slightly, to sent event message after user presses any key on keyboard.

This way I can simply wait until Mailer registers successfully and then post event to service bus. And it works great, message is being sent, handler receives it and displays appropriate message.

As you can see I’ve made it so I can send up to 5 messages (just for testing reasons), each after key press. But let’s see what happens if Mailer application crushes while processing an event. After publishing an event see that it’s handled by subscriber correctly. Than close subscriber application and send few more events from publisher. Nothing bad happens which is OK – publisher is no affected in any way by subscriber failure which is definitely what we want. But such failure cannot cause messages being lost, those events might indicate that something important has happened and in response to that some actions need to be taken. It could be very problematic if such messages were never handled. So lets restart Mailer application by right clicking on Mailer project and starting new instance from Debug menu option. What you can see is that all the messages that had been published are immediately being delivered once subscriber finishes initialization. This is great feature that takes of our minds handling subscriber failures and need to store those messages manually. NServiceBus internally uses RavenDB to effectively store and send such messages.

Let’s stop for now, this is just a tip of an iceberg that NServiceBus is and I hope to learn a lot more about it and hopefully use it in production one day. And I will of course try to share all I will learn about it in here.

Advertisements

Trying out NServiceBus part 2: No endpoint configuration found in scanned assemblies

In previous post I’ve shown how I have set up my testing environment to have some fun with NServiceBus. In the end everything seemed to be OK, yet while trying to start the application exception has been thrown saying that no endpoint configuration has been found, even though I’ve created one.

First I googled my issue trying to find out what’s going on and immediately I’ve found this thread on Stack Overflow: The dreaded “No endpoint configuration found in scanned assemblies” NServiceBus error. As the answer to the question states, this exception can be thrown in numerous situations, leaving to developer to find out which reason is the actual one in each case.

After confirming that my assembly .NET version and NServiceBus target versions are the same (.NET 4.0 in my case) I decided to follow hint provided by exception and the SO answer: create NServiceBus.Host.exe.config file and explicitly point which class should be used for configuration. The file content is simple:

The same file (with value changed to nServiceBusFun.EndpointConfig, nServiceBusFun) was created in publisher project. The value is simply namespace.className, assemblyName.

And this in fact did solve the issue from topic. But it introduced another one: BadImageFormatException. But hey! We are one step closer!
Quick googling on this exception with NServiceBus led me to this page:New NServiceBus Feature: 32-bit (x86) Host Process explaining why this exception has been thrown. Since I’m working on 64-bit system NServiceBus tries to load x64 assemblies. However by default my libraries were set to x86 mode. So I’ve changed them to Any CPU mode to make sure they are correctly working with x64 libraries.
And Voila! Mailer works, it started correctly and after few seconds NServiceBus reported that queue was created and application was waiting for messages to come.

But this left me with nServiceBusFun project, which I’ve also fixed, but now it started throwing exception saying that *.vhost.exe file cannot be loaded, and also giving a hint about how to fix this.
Exception when starting endpoint, error has been logged. Reason: Could not load C:\Users\Pako\documents\visual studio 2010\Projects\nServiceBusFun\nServiceBusFun\bin\Debug\nServiceBusFun.vshost.exe. Consider using 'Configure.With(AllAssemblies.Except("nServiceBusFun.vshost.exe"))' to tell NServiceBus not to load this file.
So I’ve updated my configuration file to implement IWantCustomInitialization interface which will give us possibility to modify configuration in code. So now the file looks like this:

which is exactly like exception said it should be. Great! Now it starts correctly, configures everything successfully and tries to send a message. But the message is not always delivered. Why? I will discuss it in my next blog post in this series.

Trying out NServiceBus

Recently I’ve been interested in building software by following Domain Driven Design approach. I couldn’t try my knowledge on any business project yet, but it didn’t stop me (and should not stop you, dear reader) from looking around for some interesting solutions to common problems. One of the problem is communication between Bounded Contexts and signalling that some actions have been performed. Very natural seems concept of Domain Events. But you need some way to easily propagate such events between elements in your system, making sure it reached all interested parts. Here comes NServiceBus. So I wanted to try it out and create simple test application to see how easy it is to start working with this library. Well, it is harder than I expected, thus this blog post for you, dear reader, and mostly for me for future reference.

First you need to download NServiceBus and install it on your machine. There is free basic licence available allowing you to send 1 message per second, which seems enough for testing purposes. There are also other licences available, so you can choose one that suits your needs perfectly. But you don’t need to download installer from their page since there is very handy NuGet package that will install NServiceBus and all dependencies for you.

I’ve created very simple solution with 3 projects in it: Mailer – will be used as message handler, faking e-mail sending service; Messages – shared between handlers and main application, defines message contracts; nServiceBusFun – application that will be sending events. That should be enough for my purposes. I’ve installed NServiceBus to both Mailer and nServiceBusFun projects. Messages project needed only NServiceBus.Interfaces library as a reference.

As a next step I’ve created simple event message that should pretend to be business event that could happen in business system.
Nothing fancy here, simple class that implements IMessage interface (which comes from NServiceBus.Interfaces) and it’s great that creating message is that simple. Of course there is more you can do with messages, but for trying it out it is enough.

After that I’ve created EndpointConfig.cs files, one in Mailer and one in nServiceBusFun projects. Those classes provide NServiceBus with configuration for endpoints, and both files are very similar, as you can see below.

One is simply marked as a server (this is mailer, since it recieves messages from clients) and the other is marked as publisher (nServiceBusFun, since it’s posting events to service bus).

So we have a message, now lets create handler. I’ve created ClientRegisteredHandler.cs file with this content:

No thrill here as well; interface tells that this class can handle messages for given type (in this case ClientRegistered). Handle method is invoked when NServiceBus gets such message. Simple and clean, just like we want it.

Our system would not give us much inside into NServiceBus if we would not create some class to publish events. So in nServiceBusFun project I’ve added this simple class:

Also pretty self-explanatory. NServiceBus will instantiate object of this class on start up and call Run() method.

Seems that all that we wanted to do is ready, isn’t it? If we run both Mailer and nServiceBusFun applications it should be OK, our client will be started, will post event informing all interested parts of the system that new client has just registered, Mailer application will get this message and pretend to send an e-mail.

But it does not work, at least for me. What it gives me is an exception on start of nServiceBusFun application that it could not find service configuration. By default it searches through all libraries in runtime folder looking for all classes that implements IConfigureThisEndpoint interface. I did this in EndpointConfig class which is in the same assembly as other parts of application, so it should work but it does not.

No endpoint configuration found in scanned assemblies. This usually happens when NServiceBus fails to load your assembly containing IConfigureThisEndpoint. Try specifying the type explicitly in the NServiceBus.Host.exe.config using the appsetting key: EndpointConfigurationType, Scanned path: C:\Users\Pako\documents\visual studio 2010\Projects\nServiceBusFun\Mailer\bin\Debug\

In next post I will try to explain why and how to fix this.