Jul 12

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.

Jul 01

Opening my Inbox this morning resulted in a pleasant surprise from Microsoft. I have been presented with the 2009 Microsoft® MVP Award as a recognition for sharing my expertise in Visual C# with others. It is an honor to be recognized by Microsoft for doing something that I truly enjoy – building really cool software.

MVPbanner.png

Microsoft Most Valuable Professionals (MVPs) are exceptional technical community leaders from around the world who are awarded for voluntarily sharing their high quality, real world expertise in offline and online technical communities. Microsoft MVPs are a highly select group of experts that represents the technical community’s best and brightest, and they share a deep commitment to community and a willingness to help others.

A community-based award like this would not be possible without the support of my peers, and I look forward to meeting up with some of those very peers at the next MVP Summit! In the meantime, congratulations to all the new and renewed MVPs!

Jun 18

It’s been a couple of busy weeks! The weekend before my presentations in Arkansas, I decided to forego sleep and go to Wakarusa! The Saturday lineup included two of my favorite electronica acts, Shpongle and Ott, and introduced to another band STS9. Staying up all night dancing to heavy techno music and getting no sleep was one heck of a prelude to the week. After the seriously fun times I stopped in on the Fort Smith and Northwest Arkansas .NET user groups and shared my thoughts on Event Driven Architecture. Both nights went well, with some great conversations afterwards about the how and why that took me towards that style of architectural system design.

Tomorrow morning at 9:00 AM (hey, if you aren’t first, you’re last — this is Texas after all) I’ll be presenting at Dallas TechFest on the same subject in the .NET track. If you want to learn more about Event Driven Architecture and how we are making it easier to implement with MassTransit, come by and check it out. I promise to deliver a demo that includes all sorts of cool things like NHibernate, FluentNHibernate, StructureMap, Castle, Topshelf, Magnum, and of course, MassTransit.

Also, if you’re in the Tulsa area and weren’t able to make it to Dallas TechFest, I’ll be presenting at the Tulsa .NET User Group on the 29th of June as well. If you do come by, be sure to stop afterwards and say hello. I’ll be at the event throughout the day and am more than happy to talk to anyone interested in learning more about MassTransit. I’m sure I’ll be around the functional programming open space playing with crazy monadic parsers written in C#.

May 22

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.

Apr 07

One of the really cool features that is available in the 0.6 release of MassTransit is the ability to declaratively define a saga/workflow using a nested-closure syntax in combination with a fluent builder. While some wonder if fluent interfaces are going to become the “aluminum wiring” of the current generation of software development, I find them incredible valuable for building an expressive representation of logic.

A saga is a way of defining a long-lived transaction, typically involving multiple transactional actors. A workflow is a way of orchestrating a number of actors into a process. Both sagas and workflows can be modeled using the new declarative syntax. First, let’s look at what this new language looks like in code:

static DrinkPreparationSaga()
{
	Define(() =>
		{
			Initially(
				When(NewOrder)
					.Then((saga, message) => saga.ProcessNewOrder(message))
					.TransitionTo(WaitingForPayment)
				);

			During(WaitingForPayment,
			       When(PaymentComplete)
			       	.Then((saga, message) =>
			       		{
			       			Console.WriteLine("Payment Complete for '{0}' got it!", saga.Name);
			       			saga.ServeDrink();
			       		})
			       	.Complete()
				);
		});
}

(I’ve removed the class structure around the constructor to keep the code short)

If we read from the top down, it is easy to understand the behavior for this saga. Initially (which signifies the creation of a new saga based on an event in this block), when a NewOrder is received, then we’re going to call the ProcessNewOrder method on the saga passing it the message that was received. Once that method completes, the saga will transition to the WaitingForPayment state. During the WaitingForPayment state, if a PaymentComplete is received, the saga will output a message, call the ServeDrink method on the saga, and complete.

The states and events of the saga are defined by adding some static properties to the class:

public static State Initial { get; set; }
public static State Completed { get; set; }
public static State PreparingDrink { get; set; }
public static State WaitingForPayment { get; set; }

public static Event< NewOrderMessage > NewOrder { get; set; }
public static Event< PaymentCompleteMessage > PaymentComplete { get; set; }

The static constructor for the state machine initializes these properties during the definition of the behavior as part of the Define() call. It is nice to be able to see all the states and events for the saga in one place, as well as the messages that are related to the events.

Another great feature allows us to ask the saga state machine engine to tell us what it is going to do based on how we defined the behavior of the saga. The StateMachineInspector class is a tool that will output a trace of the defined behavior of the state machine. For the above saga, the output looks like:

	During Initial
		When NewOrder Occurs Containing NewOrderMessage
			(custom action)
			Transition To WaitingForPayment
	During PreparingDrink
	During WaitingForPayment
		When PaymentComplete Occurs Containing PaymentCompleteMessage
			(custom action)
			Transition To Completed
	During Completed

This information is generated by using expressions and reflecting over the class and types contained. The above example is taken from the Starbucks example in the MassTransit trunk. For a service to subscribe and handle sagas like this, the service only needs to call:

var unsubscribe = bus.Subscribe< DrinkPreparationSaga >();

Like all component-based consumers in MassTransit, the container should know how to build the saga and needs to have a ISagaRepository< T > implementation for the saga as well.

I hope as more people start to use this syntax that it evolves in a really rich was of doing code-first workflow and saga definitions. One thing we definitely want to do is take the text-based visualization of the saga and output it in a format that can be used by GraphViz or MSGLEE to get a nice diagram of the behavior of the saga. Hopefully that will be coming sooner rather than later!

So that’s one of the really cool features of MassTransit that have been added.

Mar 30

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.

Jan 16

MassTransit supports sagas, which are long-lived transactions consisting of multiple events. The saga support makes it easy to orchestrate the events into a process, but it doesn’t do much to help with state management. Since state management is fairly common, I felt it necessary to add some support for a state machine.

In MassTransit, a saga is defined by creating a class and attaching some interfaces for the messages that will be consumed. The messages are the events, and the class is the saga. An example saga is shown below.

   public class DrinkPreparationSaga :
        InitiatedBy < NewOrderMessage >,
        Orchestrates < PaymentCompleteMessage >,
        ISaga
    {
        public void Consume(NewOrderMessage message)
        {
        }

        public void Consume(PaymentCompleteMessage message)
        {
        }
    }

I’ve omitted the code for each consumer to keep it short, but the business logic defined would handle the fact that once the drink is prepared, it should not be served until the PaymentCompleteMessage has been received. Storing this state is an application concern.

While I was at QCon San Francisco, I attended a tutorial session on DSLs. It was here that I got the idea to somehow make a DSL for defining the behavior of a state machine that could be used with sagas in MassTransit. It’s taken a couple of months, but I think I’ve managed to put something together that simplifies state management in sagas. With the addition of a new state machine in Magnum, along with persistence support for NHibernate, it is now easy to manage this state automatically.

To demonstrate this, below is the state machine for the above process.

	public class DrinkPreprationStateMachine :
		StateMachine < DrinkPreprationStateMachine >,
		ISaga,
		InitiatedBy < NewOrderMessage >,
		Orchestrates < PaymentCompleteMessage >,
		Orchestrates < DrinkPreparedMessage >
	{
		static DrinkPreprationStateMachine()
		{
			Define(() =>
				{
					Initially(
						When(NewOrder)
							.Then(saga =>
								{
									// start preparing the drink
								})
							.TransitionTo(PreparingDrink));

					During(PreparingDrink,
						When(DrinkPrepared)
					       	.TransitionTo(WaitingForPayment),
						When(PaymentComplete)
					       	.TransitionTo(WaitingForDrink));

					During(WaitingForPayment,
					    When(PaymentComplete)
					       	.Then(saga =>
					       		{
					       			// publish drink ready message
					       		})
					       	.Complete());

					During(WaitingForDrink,
						When(DrinkPrepared)
					       	.Then(saga =>
					       		{
					       			// publish drink ready message
					       		})
					       	.Complete());
				});
		}

		// event and state definitions not shown, but are simple properties
	}

As shown above, all the logic of states, events, and transitions is wrapped into a clean fluent interface. The During() blocks define what is to be done when events are received during a particular state. The When() blocks define the behavior when the specified events occur. All state transitions are explicit, allowing them to be captured as part of the state machine.

There are two types of events. BasicEvent supports an event without any accompanying data. The DataEvent < V > allows data to be associated with an event. In MassTransit, each DataEvent would have a matching Consume() handler. For example, Event < NewOrder > would have a public void Consume(NewOrder message) that would call RaiseEvent(NewOrderEvent, message) to pass the event to the state machine along with the message.

The state machine also supports inspection, allowing the definition to be output for verification that the intent was properly conveyed by the interface. This not only makes it possible to verify the flow between states, but also could allow the creation of a graph to display the states, events, and transitions in a visual manner. The provided state machine inspector currently only outputs to the trace window, but could easily be enhanced by somebody with some skills.

Also, not shown above, is the ability to specify an expression using the .And() method to evaluate the data associated with an event to determine if that event is handled by that state event action. This expression is kept as an expression, allowing the details to be output using the inspector as well.

Currently, the saga must still implement the Consume() method for each message and call RaiseEvent() on the state machine to pass the message and trigger the event. I plan to add some new message sinks to the message pipeline to make those methods unnecessary, mapping the messages directly into the event handlers within the state machine. This isn’t done yet, but it is planned.

The StateMachine also provides an IUserType implementation for NHibernate in the Magnum.Infrastructure assembly. This makes it easy to persist the state using NHibernate, storing the current state as a string. This is just the default implementation, any other could be built if your needs are different.

I originally presented this syntax during the Virtual ALT.NET meeting last week. It was a last minute presentation, so I wasn’t sure I covered all the details. Hopefully this will help provide some guidance on how it is used, along with plans for the future.

Nov 05

Last weekend, Dru Sellers and I (along with 100 or so others) attended the Continuous Improvement in Software Development (referred to as KaizenConf, likely due to the URL) conference in Austin, TX. We left Tulsa late Friday night after taking my girls trick-or-treating for Halloween and drove all night arriving in Austin around 5:30 AM. After a quick nap and a shower, we went to the first day of the conference.

The night before at the opening, those who were there put up a series of topics that they wanted to discuss. One of those talks was on Enterprise Service Bus (ESB) patterns and implementations using MassTransit. I think it was pretty obvious where Dru and I were going to spend our time right after lunch. There were a number of people that we have had conversations with that also attended and they were excited to learn more about distributed application designs and how to implement them using open-source tools like MassTransit.

IMG_0093.jpg

The First Session: Alternative Architectures

After the morning announcements, Dru and I joined Ben Scheirman and Ayende Rahien in a conversations about alternatives to the RDBMS. The conversation started a bit rough, but quickly opened up into other ways to store data in our applications. Ayende brought up CouchDB and the things he learned about it. There was also some in depth discussions about proper use of databases and separating transactional data from reporting to avoid transaction blocks. Some concepts on how to achieve the appropriate separation, including asynchronous ETL (extract-transform-load) were discussed. The Map/Reduce algorithm was also covered and some examples were given in the discussion of how to map data into dimensions for reporting. The proceedings from this talk can be found on the wiki.

IMG_0094.jpg

The Second Session: Lean Architecture

My second session of the day was on Lean Architecture. This discussion was forward looking and related to how development teams could branch out and work on features with the intent of releasing individual features as they are complete (instead of waiting for a big release with many unrelated features). There was a lot of talk about how the teams work, how version control and build processes would need to adapt to handle the complexity of dealing with multiple development versions of a single code base. I think one of my biggest take aways from this session was the need for an integration branch that is created from the trunk before each merge. It is then possible to integrate a branch into the trunk without immediately impacting the trunk. Once the simulation branch merge is complete and tested, the simulation is merged into the trunk (which should be easy, since it was created from the trunk originally). This alone would help to ensure a solid trunk that can be delivered on demand. The proceedings from this talk are also on the wiki.

Over lunch we enjoyed some amazing Austin weather while talking about projects and recent events. We then went to setup for the discussion on ESB/MassTransit. Upon arrival, we were surprised at the number of people in attendance. There was a crowd of at least 20 people and the video crew was setup with remote microphones and the works. Once we had gotten the projector setup and demos loaded, we started into the discussion.

The Third Session: ESB Patterns and MassTransit

The conversation started with a general discussion about messaging patterns. A reading list was presented, along with the major patterns that are used in a publish/subscribe system like an ESB. Applications for this type of system including everything from a command/query interactive system to migrating a batch processing application to a more real-time asynchronous process. We touched on where MassTransit was in the development lifecycle and some of the things we learned over the last year of development. We showed some of the sample applications, including the new web service bridge sample for connecting external customer web services to an internal domain.

Needless to say, we were amazed at the response we got related to MT and ESB patterns in general. It was great to have Ayende and Jeremy Miller bouncing ideas around regarding the project and integration with other existing systems. The notes from the discussion are located on the KaizenConf Wiki.

The Last Session: A Mixed Bag

My last session of the day was split between two completely different sessions. One was on Advanced IOC usage, and the other was on moving from Project to Product. I bounced between these two sessions, picking up some interesting bits from each one. Both were late in the day, so I was fading pretty fast considering I only had 90 minutes of sleep the previous night. Good concepts were captured in the notes, so be sure to check those out (I’ll have to just to remember them).

After the sessions for the day, we went to the Hyatt with Ben (B#) and provided input as he started writing a new sample for MassTransit. The context for this new sample was the Gregor Hohpe article about how Starbucks Does Not Use Two-Phase Commit. This was mostly a learning exercise for Ben, however, we gained some insight watching him build it out. I think Dru refactored the host quite a bit to remove some extraneous ceremony that was just unnecessary. Once we had the first bits working, it was time to find some dinner and the rest of the gang. We had some great Tex-Mex at Trudy’s and then went back to the hotel bar to watch Texas Tech put the smack down on U-Texas Longhorns.

The next morning we met up at Starbucks (go figure) to complete the new sample Ben was building (yes, the irony of working on a sample about Starbucks @ Starbucks didn’t get past us). We ended up converting from using regular message consumers to a saga-based approach given the requirements and it took another 30 minutes to get it all working. Oren had some great ideas on how we could tweak little things here and there to eliminate some friction as well. Once we were done, we headed on over to the conference to see what was in store for the morning sessions.

This year, the focus of the conference was on continuous improvement. Therefore, instead of just having additional sessions on Sunday morning the attendees voted on sessions that they wanted to help improve. At least, that’s how I understood it, we were working on the Starbucks sample, remember? Anyway, when we arrived we found that the ESB Patterns session was one of the topics. The room was full with something like 22 votes on the page. I was surprised to see the response of the people, truly surprised.

Continuous Improvement: ESB Patterns and MassTransit

The actions are summarized on the wiki, and included things like documentation, more sample applications, and help on how to add messaging to an existing application. We also dug into the things needed to help people build and understanding messaging components in their applications. Things like diagnostics, conventions to avoid common missteps, hands-on labs to walk through building a message-based component, and a few other getting started items were brought up. From a technical side, we talked about additional patterns such as an overall conversation id to correlate multiple sagas (like a saga of sagas), as well as built-in support for compensation.

A large part of the discussion was on how functional programming features could be used to enhance the system. An example in Erlang of a message exchange was drawn up, along with how it might be written in C#. Matthew Podwysocki was consulted on how this example might be written in F#, and there was discussion about how the threading model of F# doesn’t really support the style used by Erlang. Some work is still needed there I suppose but we’ll continue to be open about the possibilities offered by functional languages. Glenn Block also talked about getting in touch with the connected systems group to see what they could offer.

IMG_0095.jpg
County Line BBQ

With that, the conference was closed. Once again, the open space technology used for the event was awesome. The rules of open space dictate that what happened is the only thing that could have happened, and I agree with that completely. It was great to be a part of yet another excellent event and I look forward to future installments in other locations. Be sure to keep up with the wiki, as videos from most of the sessions will be made available online soon. One of our improvements was to better document our proceedings, and I think we’ve managed to succeed on that one for sure.