Service Bus Applications using Fubu Transportation

In today’s world it is more and more useful to have a system architecture where your system is distributed, for many different reasons. Splitting up your software into separate services can have a lot of benefits. Today we’re going to talk about one of the ways to overcome some of the problem that comes from splitting up your system, particularly over a network.

Your systems are going to need to be able to talk to each other over the network. You’re going to need ways to connect these services so they know how to talk to each other. They need to know how to ask for information or tell another what they know or what they need done. We’ll do this through a ‘messaging’ system. You’re going to need to handle dropped messages and other problems imminent with work over the wire.

Our company uses an OSS product called Fubu Transportation. It has changed names a few times, been pushed inside the main framework, pulled back out etc. But its job is to coordinating messages sent between different parts of the system.

First, you need some sort of Transport system. Fubu Transportation uses Lightning Queues. The transport is in charge of queuing up the messages and making sure they arrive where they are supposed to. It uses LightningDB for this. You can just use local storage, or you can hook it up to a database, generally a document Database. This allows it to be persistent and store the messages in case the receiver is unavailable or the service goes down before it is ready, or even schedule messages to be delivered at a later time.

The first thing you’ll do is set up a settings class that will house your channels. It needs the transport, port and a queue name.


public class TransportSettings
{
  public Uri Pinger { get; set; } =
    "lq.tcp://localhost:2342".ToUri();
  public Uri Ponger { get; set; } =
    "lq.tcp://localhost:2343".ToUri();
}

You certainly could use your choice of extracting this out into some type of settings convention and using configuration for these values.

Next you will configure the channels using FubuTransportRegistry<T> where T is your Settings class you defined above. There is a fluent interface off of a Channel() method to describe what each channel does and how.


public class PingApp : FubuTransportRegistry<TransportSettings>
{
  public PingApp()
  {
    // Configuring PingApp to send PingMessage's
    // to the PongApp
    Channel(x => x.Ponger)
      .AcceptsMessage<PingMessage>();

    // Listen for incoming messages from "Pinger"
    Channel(x => x.Pinger)
      .ReadIncoming();
  }
}

public class PongApp : FubuTransportRegistry<TransportSettings>
{
  // Listen for incoming messages from "Ponger"
  public PongApp()
  {
    Channel(x => x.Ponger)
      .ReadIncoming();
  }
}

Accepting incoming messages

Options off of Channel():
Listens on a specific channel for incoming messages.
.ReadIncoming()

Accept a specific message type
.AcceptsMessage<PingMessage>()

Specific message like this.
.AcceptsMessage(typeof(PongMessage))

Accept messages by some sort of naming convention
.AcceptsMessages(type => type.Name.EndsWith("Message"))

Specify a type within an assembly and accept those types
.AcceptsMessagesInAssemblyContainingType<PingMessage>()

Assembly by name
.AcceptsMessagesInAssembly("MyMessageLibrary")

Accept by namespace
.AcceptsMessagesInNamespace("MyMessageLibrary")

Namespace containing type
.AcceptsMessagesInNamespaceContainingType<PingMessage>()


Message Persistence:

This ignores any persistence and just delivers the message
quickly without persisting it
.DeliveryFastWithoutGuarantee()

Default, but explicitly says you want to persist messages for safe delivery
.DeliveryGuaranteed()

Fubu Transportation has some continual messaging that it does to coordinate activities like setting up subscriptions, and health checks. You should set up a control channel for this.


public ControlChannelApp()
{
  Channel(x => x.Control)
    .UseAsControlChannel()
    .DeliveryFastWithoutGuarantee();
}

Message Consumers

Next we’ll look at how to handle or consume these messages.

We will create consumer methods. FT discovers these by just being a public method on a public class that has a single parameter of the message type that is handles.


public class SimpleConsumer
{
  public void Consume(PingMessage message)
  {
    Console.WriteLine("I handle PingMessage");
  }
}

Fubu Transportation supports the idea of what we call Cascading Messages.
This is a behavior of being able to create reply messages and/or sending another message after one message is processed, all by convention without explicitly setting up more service bus code to send another message. This is done by changing the return type.


public class CascadingConsumer
{
  public MyResponse Consume(MyMessage message)
  {
    return new MyResponse();
  }
}

When FT executes this consume method, it “knows” that it needs to then send out another message of type MyResponse, with what ever delivery rules apply to its type. FT keeps track of this delivery as one transaction. It will not send the next message until the first message has been fully executed. This also helps with unit testing a lot, because you can check the state of objects within the consume method without having to re-mock the entire bus call here.

You can also use the .Request<T> method instead of a standard .Send() to tell the handler that you’re the one that wants the message back, instead of using the existing routing rules.


public Task<MyResponse> GatherResponse()
{
  return _bus.Request<MyResponse>(new MyMessage());
}

Can be handled by


public MyResponse Consume(MyMessage message)
{
  return new MyResponse();
}

You can also set up conditional responses to send different messages depending on conditions in the consumer. Just set the return type to object, and when the message is returned, it will pick up the configuration for its type and be delivered to where it belongs.


public class ConditionalResponseConsumer
{
  public object Consume(DirectionRequest request)
  {
    switch (request.Direction)
    {
      case "North":
        return new GoNorth();
      case "South":
        return new GoSouth();
    }

    return null;
  }
}

You can also schedule messages for a later time or date.
Note, persistent storage is a good idea here.


public DelayedResponse Consume(DirectionRequest request)
{
  // Process GoWest in 5 minutes
  return new DelayedResponse(new GoWest(), TimeSpan.FromMinutes(5));
}

You can also return multiple cascading messages by setting the return type to IEnumerable<object>


public IEnumerable<object> Consume(MyMessage message)
{
  // Go North now
  yield return new GoNorth();

  // Go West in an hour
  yield return new DelayedResponse(new GoWest(), TimeSpan.FromHours(1));
}

Dynamic Subscriptions

In your application’s Transport Settings file you should be setting up different channels for incoming and outgoing messages to separate concerns.


public class NodeSettings
{
    // This uri points to a different
    // application
    public Uri OtherApp { get; set; }

    // This uri should be the shared
    // channel that all nodes in the
    // application cluster are reading
    public Uri Receiving { get; set; }
}

Now you’ll configure a local subscription for each individual node of the application and a global subscription if you have the same service being load balanced on several servers.


public class LocalApp : FubuTransportRegistry<NodeSettings>
{
  public LocalApp()
  {
    // Explicitly set the logical descriptive
    // name of this application. The default is
    // derived from the name of the class
    NodeName = "MyApplication";

    // Incoming messages
    Channel(x => x.Receiving)
      .ReadIncoming();

    // Local subscription to only this node
    SubscribeLocally()
      .ToSource(x => x.OtherApp)
      .ToMessage<OtherAppMessage1>();

    // Global subscription to the all the
    // running nodes in this clustered application
    SubscribeAt(x => x.Receiving)
      .ToSource(x => x.OtherApp)
      .ToMessage<OtherAppMessage2>()
      .ToMessage<OtherAppMessage3>();
  }
}

FT uses subscription persistence to store information about the list of active applications, nodes, and subscriptions. It has built in message types for SubscriptionsChanged, SubscriptionRequested, and SubscriptionsRemoved that it uses to coordinate subscriptions across running nodes and applications.

When a FT service bus application is initialized, it:

  • Loads the same information about any other nodes in the logical application cluster from the subscription storage
  • Loads the list of previously persisted message subscriptions
  • Sends out SubscriptionRequested messages to request dynamic subscriptions

  • Sagas

    FT supports the idea of Sagas, which are basically long lived message processes.

    Think of a state machine. There is a main Saga Object that has all the logic for transitioning between different states and what should happen when that happens. Then there are individual saga states that get run through the system.These objects are durably stored. Events are published through messages that include the current state and what event happened. It gets passed through the state machine and it updates the object accordingly and then emits a completed message so the rest of the application can react accordingly as well.

    Prism: lightweight, extensible syntax highlighter

    In the process of wanting to start writing some more technical blogs, I was going to want to display code snippets and examples on my posts.

    I did some searching and looking at several different implementations of getting this done. At the end of the day I ended up choosing Prism.

    The main deciding factors that I had were that it was very easy to choose your options like theme, and languages, and some other cool features through plugins. Then you generate your .js and .css files that you can load directly into your site, very light weight.

    One of the resources I found very useful while adding this functionality to my WordPress site was this tutorial . It walked me through adding the necessary files to my site and loading/ enqueue them to be picked up and loaded by the site, as I am pretty new to using a tool like WordPress to do everything for you, rather than building up the entire infrastructure myself.

    Prism makes it very easy to just wrap your examples in a set of <pre> and <code> tags, and just tell it what language with a class name on your code tag.

    <pre><code class="language-csharp">
    … code
    </code></pre>

    Turns into

    // HelloWorld.cs
    using System;
    
    public class HelloWorld
    {
      public static void Main(string[] args)
      {
        Console.WriteLine("Hello, World!");
        for (int i = 0; i < args.Length; i++)
        {
           Console.WriteLine("{0}", args[i]); 
        }
      }
    }
    

    Book Review: The Pragmatic Programmer: From Journeyman to Master

    The Pragmatic Programmer: From Journeyman to Master
    By Andrew Hunt, David Thomas
    The Pragmatic Programmer: From Journeyman to Master

    The Pragmatic Programmer has been suggested to me by almost every source that I’ve looked to for suggestions on development books. Here I will highlight some of the take aways I had from the book.
    One of the first things they get into is the idea of not committing to too much work. Be realistic about what is at hand. Don’t tell your boss that you can finish something by Friday, if it is clear that you cannot. Be flexible on the scope of the project.

    Along those lines, they spend a lot of time going into the ideas of finding out what you’re working on. Take the necessary time to prototype, to build a solid understanding of what it should do, speak with stakeholders and use a language that you can both understand. Transition that language into the code. Name your development objects after the language you are using with the stakeholders and clients so that nothing gets lost in translation.

    In agile/scrum, which we use at work, there is an emphasis on creating small ‘vertical slices’ of fully functional and deliverable product. In the book, they describe a technique of using ‘tracer bullets.’ Build the smallest piece of work that you can, that can aim at what you’re trying to hit. Does not have to be anywhere near fully functional, but lets you know if you are on track.

    I really like their mention of the ‘broken window’ philosophy. Clean things up as you go along. As soon as you have bad, ugly, fragile code (a broken window), people are less likely to keep respect for it. When they (or you!) come into your code base, if it already has broken windows, they are more likely to feel comfortable committing less than perfect code as well. If it is all in good order, reads well, works well etc then you and others are more willing and likely to keep following that pattern.

    I like their ideas of thinking in the mindset of ‘good enough.’ Scrum also emphasizes this paradigm. It is completely okay to iterate on your work and go back and forth with your users and stake holders to decide when you have met their needs. Deliver fast and often and you will know what is needed and what is not. There is nothing wrong with removing features that you thought were going to be useful, but no longer are. The same goes for the technologies you use. Just because another framework or library is going to do the job ‘better,’ if it’s going to take you twice as long to implement it or refactor to use it, it may not be worth it.

    A big part of the book is dedicated to keeping up on your learning. To most of us, this should be a no-brainer. Our technology world is moving very fast. You need to spend time every week keeping up on current technologies and researching new ones. This does not mean you have to learn everything under the sun, but you should be keeping in the loop of what is going on and learning what is relevant.

    They spend a lot of time describing how to use a good set of tools. The most important being your text editor. Make sure you are using a powerful, configurable tool. Get good at it. It will make your life much more productive. Spend time learning, using, and getting good at other tools that make your life easier as well. Build, automation, scripting, configuration, generation tools etc.

    Motivation to start blogging

    I would like to tell you a little bit about my motivation to start a blog.

    My employer is pretty generous when it comes to learning.  They offer a lot of dedicated time to do learning and also to do open source.  They also provide a lot of subscriptions to software licenses etc, and one of the ones that I have taken advantage of a lot is www.pluralsight.com, where you can even get a free trial, which I highly recommend!  I will have another post on how valuable pluralsight has been for me, and possibly some reviews and recommendations of courses. But until then, go grab your free trial and try it out yourself!

    Start a 10-day free trial at Pluralsight

    I have watched dozens of courses and spent countless hours learning there.  John Sonmez of  simpleprogrammer.com is one of my favorite content providers there.  I would like to say that I took the time to go look him up after I had seen a few of his courses.  But, it wasn’t until a year or so later that I started listening to podcasts in the car and heard his name mentioned that I realized that he was well known and followed up to see what else he had to offer.

    I started listening to his pod cast library, and looking at the rest of what he offered.  One of his suggestions was to create a blog.  I had always wanted a place to document my ideas and a place to share my ideas and what I had learned, both inside my company and more broad.  So I bought his blogging course which can be found here simpleprogrammer.com/blog-course.

    John has a lot of good knowledge to share, even beyond programming.  I’ve watched, read and listened to a lot of his opinions on finances, real estate and what he calls soft skills.  I think it is a really good idea to keep a good balance in your life and be able to take care of you and your body, outside of your daily work.  He has a great book that talks about a lot of this, which you can also listen to on Audible.
    Soft Skills: The software developer’s life manual
    Try Amazon Prime 30-Day Free Trial
    Try Audible and Get Two Free Audiobooks

    I think it is also important to get your learning from many different avenues.  So I suggest reading books, listening to podcasts, watching videos, pair programming with others, any training that you can find.  And, mix it up.  Don’t just learn about your primary language or frameworks or architectures that you are working in.  Find out what else is going on in the technology world.  I will have some posts on some of my suggestions.

    Hello and welcome to Smart Dev Now!

    My name is RJ Schmertz.  I am a growing software developer that would like somewhere to write down my thoughts and ideas, for a couple of reasons.  I’ve always believed that reiterating something will help you remember it better, it can be living documentation and who knows, maybe I’ll be able to share some of my knowledge and experience with some others.

    My goal for this blog is to capture information that is in my head, things that I have to learn or knowledge that I will gain as I go along.  And, to share that here.

    I currently work for a pretty large global corporation in a dev shop that primarily writes services, tools and web applications on a C# .NET backend with a mix of technologies for our javascript frameworks, primarily AngularJS and ReactJS.  We have a good amount of legacy code in older frameworks like WPF, Knockout & Backbone, and even Silverlight.

    We are a little bit unique in the fact that we write almost 100% of the software that we use.  We have large call centers and we’ve created all the software that keeps the call center running, from call routing and administrative tools to the actual software the agents are using, the services that handle all the data and transformations, integrating with 3rd parties all over the world to distribute that data, service bus software to handle the distributed nature of the work, internal web tools and of course a public facing website for our main product.

    I feel blessed to work for a company where I get to touch so many types of software, in so many different languages and architectures.  But, as you can imagine, it keeps my mind busy.  I am constantly learning something new for every project that I touch.  Which I love!

    So, that is why I’m here.  I need a dumping ground for all of the knowledge that is going through this brain of mine.  I hope to remember some more things, have some things documented, help some others learn, and maybe meet some cool people on the way.

    Thanks for visiting!