Tuesday, January 4, 2011

NServiceBus 3.0: Fault Management

In NSB 3.0 we get some better support for message faults. Prior to 3.0 we were able to capture messages that faulted after a configurable number of retries. The difficulty with this is that since the actual exception was not captured with the fault, we as developers weren't able to do to much with that message besides blindly replay the message. In 3.0 this all changes in that there is a dedicated set of classes for fault management. Below is a class diagram of the hierarchy.





















Out of the box we get 3 ways to manage faults.  The Forwarder simply does what NSB has done in the past, which is move the message to a designated queue.  The InMemory manager simply holds the message in memory for the lifetime of the host process.  Lastly, the NHibernate Fault Manager allows us to store the message along with the exception that caused it to be faulted.  This allows us to be smarter about how we handle faults.

To follow along you will need to download the 3.0 branch from GitHub and build it.  From there open up the "FaultHandling" sample.  When I downloaded this sample, it did not work right away.  If you fire up the solution, nothing really happens.   First and foremost you have to change the MyClient project endpoint to be transactional.  If it is not, the fault management gets skipped right over in code. Simply edit the EndpointConfig.cs file to configure it AsA_Server.
public class EndpointConfig : IConfigureThisEndpoint, AsA_Server {}
The next issue I ran into is that the default profile(Lite) gives us the InMemory Fault Manager. The sample configured this via the IWantCustomInitialization insertion point. The only way I managed to get this to work was to move it to a custom profile, aptly named "Custom"
class Custom : IProfile{}

  class CustomProfile : IHandleProfile<Custom>
  {
        #region IHandleProfile Members

        public void ProfileActivated()
        {
            Configure.Instance.InMemorySagaPersister();
            Configure.Instance.NHibernateFaultManagerWithSQLiteAndAutomaticSchemaGeneration();
        }

        #endregion

  }
Now that we have everything configured appropriately we can run MyClient. After launching the solution, simply enter an "s" to send a few messages. Sooner or later one of them will fail and start the retry cycle. Once that is complete, the NH Fault Manager kicks in and pushes the messages to SQLLite in my case. Here is what the output looks like:
Next we can dive to SQLLite to see what the output looks like.  Note that the Message column hasn't been populated, but I'm hoping this simply a SQLLite issue.
From here we can now make better decisions on what to do with these faulted messages.  I'm going to try using a full fledged SQL Server instance to see if the "Message" column gets populated.  If not, looks like I'll be reporting a bug.

3 comments:

  1. I want to thank you for the excellent series of articles on NSB. I must admit I've been a bit lax with keeping up to date on things but I'm pleasantly surprised to see a 3.0 release. Unfortunately, I can't seem to find a 3.0 branch, as mentioned in the article, at: https://github.com/NServiceBus/NServiceBus/branches

    Is it not available yet?

    ReplyDelete
  2. The 3.0 branch is the same as the main trunk or "master" branch.

    ReplyDelete
  3. FaultManagers are in NSB 2.1 too.

    Great article. 10x

    ReplyDelete