Category Archives: MSMQ

MassTransit v2.0 Beta Available Now on NuGet!

After what seems like a long slumber, along with work being done on other projects such as Topshelf and Stact, it is our great pleasure to announce the first beta release of MassTransit v2.0. What originally started out as a minor “1.3” update has turned into a full-out cleanup of the codebase, including a refinement of the configuration API. Since there were some breaking changes to the configuration, we felt a 2.0 moniker was better to ensure users of the framework understood the depth of the changes made.

And what a list of changes it is (TL;DR = We filled it with awesomeness):

  1. Configuration
    MassTransit v2.0 now includes a streamlined configuration model built around an extensible fluent interface (inspired by Stact and Topshelf and sharing a common, consistent design). As a result, getting started with MassTransit is now easier than ever. In version 2.0, all configuration starts with the ServiceBusFactory and Intellisense guides you from there forward. The result is a clean, understandable API and a quicker out-of-the-box experience.

  2. Container-Free Support
    With the release of MassTransit 2.0, using a dependency injection container is now optional. When we started MassTransit, we leveraged the container extensively to assemble the internal workings of the bus. As we added support for other containers, required features that were not supported by a particular container led to some creative solutions (read: hacks) that were less than optimal. By moving away from a “container-first” approach, we have increased the reliability of the software and now provide container-specific extensions to subscribe consumers from the container in one simple step. We also threw in support for Autofac!

  3. Quick-Start
    By simplifying the configuration, and dropping the need for a container, it is now fast and easy to get started using our new QuickStart:
    http://docs.masstransit-project.com/en/latest/configuration/quickstart.html

  4. #NuGet
    NuGet packages have been added for the base MassTransit project, with any external dependencies (log4net and Magnum) resolved using the proper NuGet packages. Any additional references are downstream in additional NuGet packages, such as support for persisting sagas using NHibernate (MassTransit.NHibernate), and the various dependency injection containers supported.

  5. Multiple Subscription Service Options
    In addition to the existing RuntimeServices included with MassTransit, an all-new peer-to-peer subscription service has been added. By leveraging the reliable multi-cast support in MSMQ, services can now exchange subscription information without the need for a centralized subscription service. To ensure everything is setup correctly, a VerifyMsmqConfiguration method has been added that will check the installation of MSMQ and install any missing components. This is the first iteration of multi-cast support, and we need to get some mileage on it. In the meantime, the original run-time services continue to work as expected.

  6. Documentation
    Which brings us to the next big update. DOCS! They’re not perfect, and they’re far from complete, but we have focused on the configuration story to help get you up and running. As we see a need for more documentation in a given area, we will continue to flush out the docs appropriately. The docs are located at http://docs.masstransit-project.com/ and are being hosted by the fine people at http://readthedocs.org. [Thanks Eric!]

  7. Support for .NET 4.0 and .NET 3.5
    The project files and solution have all been updated to Visual Studio 2010 SP1. By default, all projects are now built in the IDE targeting .NET 4.0. The command-line build (which has been revamped to use Rake and Albacore) builds both .NET 3.5 and .NET 4.0 assemblies, including the run-time services and System View. The NuGet packages also include the proper bindings for the target project run-time version (you must use the full .NET 4.0 profile with MassTransit, the client profile is not supported).

  8. Transport Support
    Internally, the transports and endpoints have been redesigned to improve the support for new transports like RabbitMQ (and improve our ActiveMQ support). For example, transports are now inbound, outbound, or both, allowing us to properly leverage fan-out exchanges on RabbitMQ for publishing and subscribing to messages. There is more to come in this area as we take greater advantage of these advanced transport features. If you’re a RabbitMQ or ActiveMQ user and don’t mind getting your hands dirty, now is a great time to jump in and help improve transport support.

  9. Distributor Consumer And Saga Support
    Work on the MassTransit distributor subsystem continues to be improved. Testing on a multi-master system has been completed which will allow it to serve multiple distributors to improve load balancing efficiency. Support for all sagas (previously only state machine sagas were supported) has been added as well.

  10. Swinging the Feature Axe
    Some previous troublesome and poorly supported features (Batching and Message Grouping) were removed from the 2.0 release to reduce code complexity. Also in light of the new Parallel Tasks work in the framework the Parallel namespace has been removed.

In the next few days, I’ll be posting an annotated walkthrough of the new configuration API. In the meantime, fire up Visual Studio 2010, create ConsoleApplication69, switch to the full .NET 4.0 framework, and Add a Library Package Reference to MassTransit using NuGet. Paste the code from the Quick Start into your program.cs and check it out!

Interface Subscriptions Now Supported by MassTransit

Last year when we were reviewing the backlog of items that we wanted to build for MassTransit, one item that kept rising to the top of the list is a solid story for evolving message producers over the lifecycle of an enterprise system. Being able to publish events that current and down-level subscribers could consume was a key goal to avoid having to upgrade systems all at once when a publisher is updated. Fortunately, it hasn’t been a real concern in our application since we deploy the entire system as a whole with each delivery.

Nonetheless, a way to update a service that publishes messages without requiring every subscribing service to be updated at the same time was need.

Eliminating Impediments

Before we could implement interface subscriptions, there were a few things in the way that needed to be addressed, things that were not easy to implement.

First, we were still doing binary message serialization. While we had the ability to use the .NET XML Serializer, it tends to be slow and difficult to fit into the model we had built with MT. Back in May, XML became the default serialization format using an entirely new serializer built from scratch.

Second, we wanted to ensure that a publisher could publish a single message and have it delivered to all of the interested subscribers regardless of whether they had subscribed to the message class or one of the interfaces implemented by the class. In MassTransit, subscriptions are added by type a defined using a plain old CLR object (POCO). In the 0.6 release, we replaced the message dispatcher with a new type-based pipeline for both inbound and outbound messages. Starting with an object and working down the type structure of the message, messages are pushed through the pipeline to interested message sinks. In the case of the outbound pipeline, it makes it easy to push a class through that has interfaces, since the interfaces can be assigned from the message object. Another hurdle eliminated.

Implementing Interfaces

Once the hurdles were eliminated, it was actually very easy to add interface subscriptions. Since most of the internal bits had been reworked leveraging the power of expressions and generics, it was simply a matter of tweaking a few parts of the serializer and we were ready to rock and roll. Ensuring that message objects retain their type through the various pathways inside the system was also important, and resulted in fixing a couple of low hanging bugs related to message retry and fault publishing.

The one bit of code that needed to be built was a way to provide a backing class for an interface to store the property values. At first, I looked at using something like LinFu or DynamicProxy2 to create a proxy for the interface and intercept the property accessors, but this had a problem. I did not want property setters on the interface. At that point, I started looking at using the Emit classes, AutoMapper, the FastProperty expression-based accessors, and how Udi had dealt with it inside NServiceBus. What I ended up with was a very fast, cached object builder implementation that is integrated within the message deserializer. In the words of Cartman, “It’s pretty cool.”

There isn’t really a difference in the code between using classes and interfaces from either the producing or consuming end. While a producer will likely continue to publish a class, it just has to implement the message interface on that class, allowing the consumer to subscribe to the interface, breaking the dependency on the actual class published by the producer. The pipeline will then properly serialize out a message for that interface and send it directly to the consumer.

I’m pretty excited about this, and hope to update some of the pre-built services to use interfaces instead of classes in the near future. In the meantime, pull down the latest trunk and check it out.

Under the Covers with MassTransit Endpoints

This post details some of the internal changes to how MassTransit, an open-source lightweight service bus, communicates with transports such as MSMQ, ActiveMQ, and TIBCO. These changes are not likely to impact anyone using MassTransit, they are all well below the abstraction layer provided by the bus. At the same time, I felt it was important to share the change, along with the reasons it was made, with those that are using MassTransit.

When MassTransit was first started, MSMQ was the only transport we intended to support. In due time, however, it was determined that support for transports such as ActiveMQ and TIBCO was important. The ability to run on Linux and OS X under Mono (which does not support the System.Messaging namespace) as well as interoperability with Java systems using JMS (a specification for messaging, implemented by messaging systems like ActiveMQ and TIBCO) were the primary drivers of this decision. At the same time, insulating developers from the particulars of each transport was equally important.

To communicate with an endpoint, MassTransit uses the IEndpoint interface. The service bus would receive messages from an endpoint using this method:

IEnumerable< IMessageSelector > SelectiveReceive(TimeSpan timeout);

This involved making a call that returned an enumeration of message selectors, allowing the caller to step through the messages until an interesting message (in the case of the bus, a message with a subscribed consumer). The concerns of receiving a message were seemingly spread at random across three or four different classes (and yes, I wrote this crap). The reason for the complexity was solid though – I need the ability to selectively receive a message from a queue and skip over ones in which I have no interest.

The complexity of dealing with the yield return/break syntax of enumerators and managing scope is difficult. The programming semantics behind it are difficult to understand. I wanted something better. With all the time I’ve been spending since this was written dealing with nested closures, lambda functions, and continuations I realized there was a better way to reduce the complexity while at the same time improving extensibility.

The new signature for the receive method on an endpoint looks like this:

void Receive(Func< object, Action< object > > receiver, TimeSpan timeout);

With this new interface, the caller need only pass a method that accepts an object and returns a method that also accepts an object. The first method provides the caller an opportunity to inspect the message object to determine if the message will be consumed by the bus. If the bus is not interested, it can simply return null. If it is interested, it returns a method (either anonymous or a regular class method) that will consume the message. The endpoint will then call the returned method with the message once it has been received successfully. If the endpoint determines that the message is no longer available (if it were picked up by another process reading from the same queue for example), the returned method is not called.

The calling method looks something like this:

_endpoint.Receive(m => message => { doSomethingWith(message); });

This interface is far less complex to implement, and also made it easy to make a clean separation of what is an endpoint and what is a transport. Which leads me to…

Endpoint and Transport Split?

Sadly that reads like a Hollywood headline, but it is true. Endpoints now deal only with address resolution of sending and receiving messages and translating between the transport format and a message object (including de/serialization). New transport classes are now responsible for the actual communication with the various queue implementations supported by MassTransit.

For example, previously there was one class, MsmqEndpoint, that contained all the aspects of talking to MSMQ regardless of the type of queue (local non-transactional, local transactional, remote). Now beneath the endpoint itself, there are three MSMQ transports, one for each of these scenarios. Each of these transports cleanly deals with the particulars only, for example, the non-transactional transport has no transactional concerns in it at all.

Introducing ITransport

The new ITransport interface is narrow, dealing only with the simplest form of communication — streams. The send and receive methods from the endpoint are matched, but instead of dealing with objects, streams are used. Every transport should provide stream support at a minimum. The receive method of the transport looks like:

void Receive(Func< Stream, Action< Stream > > receiver, TimeSpan timeout);

While all transports implement streams, there is a benefit to communicating at a level above streams for certain types of endpoints. For example, when using MSMQ there are advantages to communicating directly with the Message object such as having access to the transport level message ID, the message label, and other interesting properties. To support this, the MsmqEndpoint only accepts an IMsmqTransport interface, which inherits from ITransport and adds:

void Receive(Func< Message, Action< Message > > receiver, TimeSpan timeout);

Other transports may benefit from a custom interface as well, but it is only implemented for MSMQ at this point. ActiveMQ, Loopback, and Multicast UDP all use the base stream interface.

Looking Forward

This rewrite was not purely for entertainment value (well, it was fun). Latency when sending a message from a machine to a remote queue is orders of magnitude slower than writing to a local queue. And in addition, local queues have the advantage of being local — which is important considering the first fallacy of distributed computing — the network is reliable (NOT!). To compensate for this, a more reliable method of sending messages to a remote queue is needed. By ensuring that messages sent/published by an application are durable regardless of network failure, developers can use this fire-and-forget approach to messaging that is key to building event driven applications.

To handle this, MassTransit now uses a store and forward transport for remote MSMQ queues. The store and forward transport will automatically create a local queue to cache the outbound messages destined for the remote queue. When a message is sent to the remote queue, the transport writes it to the local queue and returns to the caller. An asynchronous method then delivers the message in the background. The same transports that are used by the endpoint are reused by the store and forward transport, maintaining that high level of code reuse.

Note that on Windows Server 2003, I have observed that MSMQ will accept messages destined for a unreachable remote queue and attempt redelivery itself, but only for transactional queues (at least, that is what I have seen).

Wrapping Up

While it is always hopeful that changes like this will go by unnoticed, there is always the chance that there are some unintended consequences (read: bugs). Hopefully any of these will be weeded out quickly. In the meantime, I hope to start work on some availability features to support load balancing of command services.

Accessing ActiveMQ on Mac OSX from a Windows VM

With MassTransit, we support multiple messaging transports, including MSMQ (comes with Windows), ActiveMQ (an open-source Java message broker), and TIBCO EMS (a not-so-open-source message broker). With that in mind, teams building on the Windows platform can comfortably choose MSMQ and enjoy familiar management tools. If your needs expand to multiple platforms, however, the other choices become more important. One of our goals is to enable MassTransit to communicate between services running on Windows, OS X, and Linux. By using the Mono Project to run .NET code on OS X and Linux, and ActiveMQ to handle the messaging, we’re pretty confident that we can reach that goal.

To start working towards this endeavor, I had to first get a working test environment. ActiveMQ can run on Windows, Linux, and OS X. Since Dru Sellers and I both develop on Macs using VMware Fusion to host various versions of Windows, I wanted to install and run ActiveMQ on the Mac host, making it available to any of the virtual machines. I had not really dealt with setting up services on OS X yet, but was happy to learn that it is a pretty slick process to get things installed and running. Hopefully this will help if you decide to do the same.

I should note that I am not an ActiveMQ installation/administration expert. I am configuring ActiveMQ for use in a development environment. If you are going to use ActiveMQ in production, make sure it is configured for proper production operation with the appropriate security, storage, etc. That being said, let’s get started.

Getting Started

You need to download ActiveMQ. I got the Linux version by typing in the URL manually to get it to download using Safari. The archive will be unpacked into a tar file automatically by Safari (if not, just double-click it), which you can then open the tar file into a folder by double-clicking it again. If you are a command-line wizard, you already know how to handle the tar.gz files so enjoy.

Move the unpacked folder (apache-activemq-5.2.0 in my case) to the /usr/local folder by opening Terminal and entering:

sudo mv apache-activemq-5.2.0 /usr/local/

While still in terminal, change to the ActiveMQ folder. We need to modify the configuration.

cd /usr/local/apache-activemq-5.2.0
mate conf/activemq.xml

If you aren’t using TextMate, well, do whatever you need to do to open that file. I removed a lot of unused things from the file, but your needs may vary. You can download my configuration file if you want to use what I am using. You will need to modify the IP addresses to match your environment. I originally tried to use just localhost, but had issues with it connecting from my Windows 7 VM. If this is just a fluke, I’ll update my file later with my new settings.

Installing the launch daemon into OS X

To run ActiveMQ as a service, you need to create a property list that describes the application. This is just an XML file, but we need to create it and put it into the /Library/LaunchDaemons folder and call it com.apache.activemq so we can identify it later. You can download my version of the file to save some typing if you prefer.

ActiveMQTerminalSetup.png

Some of these settings can be adjusted if you don’t want to keep ActiveMQ running all the time. KeepAlive will automatically restart the service if it stops for some reason (including manually stopping it) and you can set that to false if you want to control it manually.

After creating the file, we need to configure OS X so it knows about the new service. To do this, type the following:

sudo launchctl load /Library/LaunchDaemons/com.apache.activemq
sudo launchctl start com.apache.activemq

Once you have done this, you can verify that it is started by running the OS X Console application (find it in QuickSilver/Spotlight if you don’t know where it is). Look at the message logs and you can see the startup messages from the service:

ActiveMQConsoleLog.png

So how do we know that we have a working installation? Well, there is an admin console that you can reach by navigating to http://localhost:8161/admin that will let you view the queues, topics, etc. that are running. You can also use the JMX tools to dig into the queues as well, including the ability to send messages to the queues directly from the Java console! To get the console started, you need to run jconsole from Terminal. Once it is started, you need to connect to the URL that is configured:

JConsoleConnect.png

Once you are in the JConsole, you can view all the queues. It should look like this (well, assuming you’ve created some queues, which I’ve done here with the Starbucks sample from MassTransit).

JConsoleView.png

You can see the default URL that was connected to in the title bar, along with the tree view of all the objects. The more interesting tab is the Operations tab, which lets you run commands against the queue. In fact, you can past some XML straight into an input box and click “sendTextMessage” and the message will be stuffed into the queue right there.

JConsoleOperations.png

So now that we know ActiveMQ is running and happy, we can modify our application to use the ActiveMQ transport instead of the MSMQ transport by simply changing the URI for the endpoint. So instead of msmq://localhost/mt_subscriptions you would specify activemq://192.168.0.195:61616/mt_subscriptions (in my case, that is the IPv4 address of my host machine). As long as the transport is in the same folder and you’re using the StructureMap base registry without specifying a specific transport, it should connect up to the host and start working. The other containers will hopefully get this support soon, it was just easy to add with the Scan() feature of StructureMap’s registry DSL.

I hope to dig deeper into the ActiveMQ transport support in MassTransit, as well as start testing it while running under Mono on OS X over the next few weeks. I already have the Windows bits working, I just want to test more exception cases such as losing the connection to ActiveMQ, as well as other runtime issues to make the code more production ready. I also want to try sending messages to/from other languages, such as Ruby via STOMP, but my Ruby skills are not the greatest.

At the very least, I hope this article helps you get ActiveMQ installed and running on your Mac using OS X Leopard. If you do run into issues or have problems, be sure to visit the MassTransit mailing list and post your questions/issues there.

Presenting on Event Driven Architecture and MassTransit

Event Driven Architecture

Business applications no longer exist as isolated systems. In order to provide integrated solutions that add business value, applications must be connected. Modern approaches for enterprise application integration (EAI) such as Service Oriented Architecture (SOA) separate applications into services that can be accessed via a standard interface such as a web service. This collection of services provides a platform on which new applications can be created that leverage the existing functionality.

However, as application complexity increases, the coupling of services becomes an impediment in adapting applications to meet the ever-changing goals of the business. Event Driven Architecture (EDA) is a method of designing and implementing systems where events are exchanged between highly decoupled components and services. EDA does not replace SOA, instead it compliments the request/response nature of SOA with a highly scalable event model for building and coordinating asynchronous transactions.

In this presentation, I will explain event driven architecture, describe the different types of events, demonstrate how events can be related and orchestrated, and provide a basic understanding of how this method can drive the architecture of enterprise systems. In addition to understanding the concepts of event driven architecture, we will explore a working sample built using an open-source .NET messaging framework called MassTransit.

You can catch this presentation at the following events:

Dallas TechFest Slide.png

If you are one or more of these events, be sure to come up and introduce yourself after the session. Also, if you have any feedback on the presentation, feel free to post your comments here or via e-mail.

MassTransit Now Speaks XML By Default

Last night, I made a major update to the trunk of MassTransit that changes the default message format from binary to XML.

Since the first drop of MassTransit, the default format for messages was binary. This had several advantages, one being the ability to take any object and just use it as a message. The BinaryFormatter in .NET is pretty hard core about making sure that the object will come out the other end without any changes. The disadvantage of using binary as a message format is it makes it very difficult to interoperate with other systems. For this reason, we are embracing XML as the new default message format.

The road to XML was not easy. Many months ago when we opened up the endpoints to a configurable serialization format, we ran into some issues with our first attempt at XML. We used the .NET XmlSerializer at first, and found it to be too limited to meet our needs. There was no support for serializing dictionaries (which I would call a smell in your message contract anyway), and you had to register the type of every object being serialized in advance in order for it work properly. With all these problems, we continued to keep binary as the default with XML being experimental.

I started writing a new XML serializer from the ground up nearly a year ago. I went through a lot of approaches and just didn’t find something that I liked using .NET 2.0 as the framework. I looked at a more Google Protocol Buffers technique for a while, but found it a little cumbersome to deal with compared to just using XML. Then, a month or two ago, I started to seriously look at how we could do a solid XML serialization attempt again using the .NET 3.5 framework features. From that research, the current default XML serializer was founded.

Like many ORMs such as NHibernate, the use of the XML message serializer requires that the objects being serialized have a no-argument constructor. It can be protected to hide it from developers, but it must exist. Also, only properties are serialized as they represent the public contract that the message object is sharing. And the properties must be read/write so that the serializer can get and set the value of the property. Here is an example of one of our messages:

public class NewUserRegistered :
CorrelatedBy< Guid >
{
public Guid CorrelationId { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public DateTime RegisteredAt { get; set; }
}

Since messages are DTOs (data transfer objects), I try to keep them clean and simple. They are pure data containers and are not meant to have any behavior associated with them. While I treat my messages as immutable, I don’t find I need to express that in the message class itself since it just tends to make the object more confusing. And quite honestly, there are better ways to express immutable message contracts, such as using interfaces.

The resulting XML for the above message looks like:

< ?xml version="1.0" encoding="utf-8"?>
<x :XmlMessageEnvelope
xmlns:x="MassTransit.Serialization.XmlMessageEnvelope, MassTransit"
xmlns:m="MassTransit.Tests.Serialization.NewUserRegistered, MassTransit.Tests"
xmlns:s="System.String, mscorlib"
xmlns:d="System.DateTime, mscorlib"
xmlns:g="System.Guid, mscorlib"
xmlns:i="System.Int32, mscorlib">
<m :Message>
<s :Username>billg</s>
<s :Email>billg@microsoft.com</s>
<d :RegisteredAt>2009-05-27T13:50:21.106875Z</d>
<g :CorrelationId>acb709df-7e32-45e2-a48c-9c160091aa5d</g>
</m>
<s :SourceAddress >loopback://localhost/source</s>
<s :D estinationAddress >loopback://localhost/destination</s>
<s :MessageType >MassTransit.Tests.Serialization.NewUserRegistered, MassTransit.Tests</s>
</x>

Namespaces are created for each type of object that is serialized. This makes it fast and easy for the deserialization process to figure out what type to use when reading the value from the XML. It’s easy to look and see the actual data that belongs to the message, as well as the headers used by MassTransit.

I wanted to post this as quickly as possible after committing the changes to the trunk so I will wrap up. I’m pretty excited about having a nice, readable message format. Since finding MSMQ Studio, I’ve really wanted to improve the diagnosis story for looking at messages inside the queues. I think this is a solid move towards that goal and a great first steps towards interoperability with other systems.

MassTransit Saga Enhancements for Event Processing

In the past year, I’ve been learning about Event Driven Architecture and how using it in the enterprise can make adding functionality over time easier through a loosely-coupled event-based architecture. With Event Driven Architecture, business components can subscribe and react to events, using correlation and orchestration to combine those events to represent business processes. The loose-coupled nature makes it easier to add functionality without modifying existing services — reducing the risk of deploying new services over time.

When I first added saga support to MassTransit, the focus was purely on allowing for long-lived transactions and the orchestration of a series of events that related to a specific process. Earlier this year, the first release of a new declarative programming style for sagas using a fluent interface was put into the trunk, making it possible to design sagas using a more natural structure and language. This feature alone is one of the more compelling things about sagas in MassTransit.

Over the past month or so, I’ve been working on extending the capabilities of sagas in MassTransit beyond the orchestration of directly correlated events (represented as messages). With the latest updates to the trunk, messages that are not directly correlated to the saga can now be observed by the saga using either the interface-based or declarative state machine based saga syntax. This makes for some very compelling functionality as sagas can now observe other events and react to them!

Let’s take a quick look at the syntax using the state machine syntax using a simple message indicating a user has signed out.

public class UserSignedOut
{
	public string Username { get; set; }
}

This message only contains the username of the user that signed out of the system. If we had a saga that tracked the state of an operation on a web site based on the current user, we could observe this message and release any resources that were being tracked by the saga. For example:

public class ShoppingCartSaga : 
	SagaStateMachine< ShoppingCartSaga >
{
	static ShoppingCartSaga()
	{
		Define(()=>
		{
			Correlate(UserSignedOut).By((saga,message) => saga.Username == message.Username);
	
			During(Active,
				When(UserSignedOut)
					.Then(saga => saga.ReturnCartItemsToInventory())
					.Complete());
		};
	}

	public static Event< UserSignedOut > UserSignedOut { get; set; }
}

The Correlate() method is used to define the correlation expression used to match a message to one or more sagas in the saga repository. With this addition, the ISagaRepository has been changed to make it more integrated into the message pipeline, along with the new pipeline message sinks to support this enhanced functionality. The pipeline viewer has also been updated to show the contents of the message pipeline, including all the messages handled by the saga. The Correlate() method can also be used to change how a CorrelatedBy message is also correlated to the saga, making it possible to override the logic on how messages are used to create/use existing saga instances.

The first use case for this new functionality was to improve the subscription service. By making Subscription and SubscriptionClient sagas observe messages from each other, the sagas are able to now complete when they see a node coming back online after a crash or going offline, etc. Since the saga repositories themselves are used to keep track of all the clients and subscriptions in the system, putting that responsibility within the declaration of the saga state machine itself makes for a really clean implementation.

These bits are currently in the trunk and will be part of the next release drop of MassTransit. I encourage you to check them out and provide some feedback on any issues. Some of this may be extended soon to also allow for the custom definition of the policy associated with how messages should be applied to sagas, such as always creating a new instance or using an existing instance of a saga. Some conventions are currently in place based on the Initial state that select a default saga policy (check out ISagaPolicy and the classes that implement it for more details there).

So check it out and keep the great feedback and comments coming on the message group. The new syntax additions should be added to the wiki soon.

MassTransit 0.6 Release Candidate

I’m proud to announce that we are getting close to a final 0.6 release of MassTransit. We’ve been working on this release since early December and have added a lot of new functionality. We’re also glad to have integrated a number of patches that the community has contributed — thanks for your help!

If you are currently developing with MassTransit, please check out the new bits and give us feedback. The trunk contains all of the latest code. A snapshot of the trunk, along with a 0.6 RC1 build have been added to the GoogleCode site. If you have any problems, comments, suggestions, or patches please post them to the Google Group for MassTransit. We’re interested in all experiences, good, bad, or otherwise.

A quick run down of the changes includes:

  • Message Pipeline
    The message pipeline is a replacement for the message dispatcher, as well as the cache-based publishing and subscribing bits. This new pipeline is built using a pipes-and-filter approach and is dynamically adjusted as subscriptions are added and removed — both locally and by remote services.
  • Saga State Machine
    With the all new method of defining sagas using a state/event fluent interface, it is now even easier to describe the business logic of a process and the events from which it is built. With the new state machine, it is not necessary to have message consumers and interfaces on your saga, you can just define the events in the class and they are wired automatically by the subscription framework. The early version of the syntax was discussed in this post.
  • Better Request/Response Support
    The old bus.Request() syntax has been replaced with a new fluent style for making requests and waiting for responses. Both synchronous and asynchronous calling conventions are supported. Look for the new bus.MakeRequest extension method for more information on this slick new syntax.
  • Code-based Configuration Syntax
    A new, code-based method of configuring and running a service bus has been added. This syntax significantly simplifies getting started with MassTransit and has been used throughout the unit tests. The facilities for Castle have also been updated to transparently use this new syntax with the same XML-style configuration in Windsor. More details on this syntax can be found here.
  • Message Headers
    Messages are now wrapped in an envelope and headers are associated with the message. The pipeline will add certain headers, and additional headers can be added by the message publisher using an extension method to the IServiceBus.Publish and IEndpoint.Send methods. Header properties such as ResponseAddress, FaultAddress, DestinationAddress, and SourceAddress make some more advanced routing options available. All three message serializers support the message headers. Which brings me to…
  • Binary, XML, and JSON Message Serializers
    All three serializers can now be configured for use as the wire message format.
  • Topshelf Integration
    The old MassTransit.Host has been replaced with the easier to use Topshelf service hosting framework.
  • Unsubscribe via Delegate
    The Unsubscribe methods on IServiceBus have been removed. When Subscribe is called, an UnsubscribeAction is returned instead. This delegate should be called when the subscription is no longer needed. This makes it easier to modify the state of the service bus in response to subscribe/unsubscribe actions by maintaining all of the information needed to unsubscribe in a lambda expression. The UnsubscribeAction is a delegate, and multiple unsubscribe handlers can be added together via the += operator. You can also use the extension method to get an IDisposable version of the subscription.
  • Redesigned Subscription Service
    The subscription service and client have been rewritten to take advantage of the new saga syntax. This reduces the number of specialized components needed for each service, as well as leveraging the features of MassTransit internally. Check out the SubscriptionManagerGUI in the WinFormSample for a demonstration of the service, as well as the pre-built services for use in your production environment.
  • Starbucks Sample Updated
    The Starbucks example has been updated to use the new saga state machines as well as some housekeeping updates to use the new features. Be sure to check it out as a starting point for understanding sagas and how to interact with them. Details on how to get the Starbucks sample running are on the wiki.

We’re hoping to get an official 0.6 release in the next couple of weeks, so please provide any feedback you have to help us wrap it up. You can get the bits, including a source and binary distribution here.