"Can I get a CustomerService with that?"
"No."
Why do we always gravitate towards the data centric services? I honestly believe its because its just easier to do. Data is always defined, whether its in DDL (CREATE TABLE ( Name char(4));) or in C# (private string _name;) we have solid ways to define data. These names and definitions make it easier for me to work with it. On top of this, it seems to me that the English language is good at describing nouns (really?), but for some reason when it comes to verbs I begin to falter (That is a brown, female, purebreed horse vs that horse can run like the wind, jump 20 feet high and dance the macarena) there is just something different in the feel of a noun being described versus a verb. I mean I am describing the noun still. Running (the thing) is an empowering experience. A workflow is a thing, the process is a thing. What is a verb? To Run, is moves me from point a to point b. Hmmmm...where was I going with this? anyways...
I ran into this naming problem last night when Chris and I were working on MassTransit. We were working on cleaning up the pipeline structure for incoming messages and we were trying a more functional approach, and I was tagged in to take the next step in the code, and I hit a big brick wall when I went to name a list of functions that returned a message consumer after doing a boolean check. What the hell do I call these things. My mind was so jarred by the lack of an object (no object here, just the function) that I couldn't come up with it (again showing my noun focus). I think I will get there, and as we worked the code a bit more I came up with better still ideas (I was starting to treat the function as a first class citizen). By the time it roles into the mainline I should have it nailed, but it served as a smack in the face that I have a ways to go.
So where is our DDL for functions (Func<TMessage, bool> check) is not the same. Its not the same because for data that's where it stops, but for a function the question is still, what is it, or rather what does it do? I think this is where we can learn alot about functional programming. Because maybe the real function definition is m=>m.InvoiceId == 2; which just happens to be a Func<TMessage, bool>...I can answer both what it is and what it does. But this is trivially simple. What if it were more complicated, like in real life?
I am having a bit of a reflective night, and wanted to share some thoughts about moving towards service based architectures. PhatBoyG asked me "What is changing, now that you are spending more time working on MassTransit, about the way you architect solutions?"
At first blush, I thought about messages and windows services, but as I have had more time to think about it, some other thoughts occurred to me.
One of the biggest changes that I have begun to see in the way I am putting systems together is that I am thinking about reusable components. After writing the last sentence I realized that I have also further refined how I define 'reusable component.' Where before it meant, a chunk of code that I could reuse inside of multiple codebases. Those that have seen my codebases know that I am a big fan of a piece of code called the SmtpMailService, and its interface MailService (for the reason why no 'I'). The problem with this is that I am continually forgetting the configuration information for the Smtp server (are we using the default ports, or alternates to avoid hackers or what not). Nowadays, I see this piece of code moving to a win service, that sits on the Smtp server itself. Now all that I have to do, to enable my applications with email services, is to reference my 'email message assembly' and explain that in order to send an email all you need to do is publish a 'SendEmail' message with the constructor filled with the correct values (from, to, subject, body) which based on the argument's names is quite obvious.
I don't have to remember how to configure the service, all I need to remember is that to send an email I need to publish this one message. This makes the learning surface for new developers extremely small, and it also helps to ensure that email is only performed in the 'approved' fashions (such as sending from a known email address, or from a specific IP Address).
So, theses are the kinds of changes I am seeing in the way I develop and architect software.
-d
Since the beginning of my foray into SOA I have heard about composing services to 'write' new services. I have never really understood how this was supposed to work. Although, vague thoughts of Windows Workflow style wizards do come to mind. One of the first books that I have read on the subject 'SOA in practice'(2) even laid out yet another layered architecture (3 layers to boot) these were called basic services, composed services, and process services. Basic services are the basic building blocks that composed services would use and the processes would orchestrate them over time, I believe. This fell very much in step with what a consultant was telling us at the time although he kept trying to talk to us about Data SOA(1) (Imagine my expression at the thought of directly exposing my database over a Web Service layer micro indeed).
I have over the last 9 months been thinking alot about this topic and been having many excellent conversations with many great minds about this same topic. And I am starting to find some very basic examples of services that I would want to reuse. Things like a time out services, a subscription service, a deferment service, an email service and a storage service. These are very prototypical in nature, but I am already enhancing business services with these external services, and I am beginning to see how this could expedite the development of robust and dependable services.
I am looking forward to future discussion with my friends and readers on this topic as well.
-d
1. http://www.rgoarchitects.com/nblog/2008/08/17/WhyTheDatabaseAsAServiceIsABadIdea.aspx
2.http://www.amazon.com/SOA-Practice-Distributed-System-Design/dp/0596529554
http://www.rgoarchitects.com/nblog/2008/02/05/TheLayeredArchitectureStyle.aspx
So I learned a lesson this week (Well actually a while ago now). Window's services have this neat feature called 'Service Dependencies.' This aspect of windows lets you set certain 'wait for it' dependencies! Awesome, this means if your service needs SQL or MSMQ to be started before it can start working windows will make sure this happens. I admit I felt a bit dumb when I wondered why my services weren't working, but my friends PhatBoyG and Scott V schooled me in some basic Win Service k-nowledge.
Since I started this blog post I have exposed this concept in the MassTransit host project. Basically trying to make windows services a bit easier and have them work well with MassTransit hosted services as well.
Watch the masstransit wiki for a soon to be written walk through of hosting a win service with MT.Host.
-d
Dru![wow]
Well, Chris and I are driving home from KaizenConf and we are still reeling a bit from all of the conversations that we had. As usual, with this group of committed students and teachers I am left feeling comforted and secured in not only the way I approach software development, but also in the way I continue to seek a better way to approach life. Enough with the platitudes and on to the real topic.
What's next for Mass Transit
Holy Shinikes! Chris and I were amazed with the number of people that were interested in the project/topic. The best part was that the discussions that we had were not so much about MT specifically, but more about how to go about building distributed systems with examples in MT. We talked about strategies of use and patterns rather than how to best leverage Consumes<T>.All. Its with these conversations that we can go back and really grind on MT to make it a tool that people can both understand and use.
THANK YOU
We were additionally impressed that the ESB topic was chosen as a follow up topic to be discussed in the action item sessions, you can see the notes here and expect to see action.
One of the big topics was documentation, consider your message heard loud and clear. There will soon be a wiki for MT (HERE) and a dedicated effort to document the published interfaces, as well as some hands on style labs, and a new and improved sample. Several people at the conference have said they would help with the documentation (THANK YOU). I have added some initial wiki topics and invite you to go to town.
One of the things that we have tried to do with MT is reduce the complexity of writing multi-threaded systems. One of the things that we discussed that we con do to make this even simpler is to study other languages. We discussed erlang and F# in the process and intend to do more research in this area to see if we can't bring in some of the other languages good parts, and make even simpler and more reliable.
So keep your eyes open and the conversation flowing.
-d
Over the past couple of months I have been thinking a lot about self-documenting systems. It all started when I was working on MassTransit's Subscription Manager and I realized that I could display this information of a web page and that would be really nice information to see. Well the current MTA has that. This week I had a new idea, what if I could draw a graph (think NDepend) of all of the endpoints and the message traffic between them!
Well, Saturday night I sat down and started to bang some code out using MsAgl, which is a pretty sweet little library. System.Drawing on the other hand is my new favorite namespace to hate on (this could be because I just don't grok how its supposed to work I suppose). Anyways, I got my spike done and I wanted to share my graph. 
You can expect to see this hit the source control in the next week or so, I just want to get the concept a bit more thought out.
Let me know what you think. Is this going to be helpful to you?
-d
Hi
Adam,
How can multiple services subscribe to the same message but only have it delivered once? I am thinking of redundancy and load balancing scenarios where I have multiple clients processing messages.
I think that you are referring to a competing consumer pattern. Assuming this is correct this is how I would go about solving it in MT.
In masstransit, we have the concept of a control bus as being different from the 'data bus'. You can see this in the XML below
<facility id="masstransit">
<bus id="server"
endpoint="msmq://localhost/mt_server">
<subscriptionCache name="subscriptioncache.shared"/>
<managementService heartbeatInterval="3" />
</bus>
<bus id="control"
endpoint="msmq://localhost/mt_server_control">
<subscriptionCache name="subscriptioncache.shared"/>
<subscriptionService endpoint="msmq://localhost/mt_pubsub">
<localEndpoint>msmq://localhost/mt_server</localEndpoint>
</subscriptionService>
</bus>
<transports>
<transport>MassTransit.ServiceBus.MSMQ.MsmqEndpoint, MassTransit.ServiceBus.MSMQ</transport>
</transports>
</facility>
Here you can see a snippet of the windsor masstransit facility where one 'autonomous component' is listening for data at 'msmq://localhost/mt_server' and is listening for control messages (things like subscription updates) at 'msmq://localhost/mt_server_control'. This setup will allow multiple consumers to happily exist. :) Each one listening for application messages at 'msmq://localhost/mt_server' and receiving at there own control endpoint 'msmq://localhost/mt_server1_control', 'msmq://localhost/mt_server2_control', etc.
I would also recommend that from an application development standpoint that your software be able to handle any given message more than once. As we move into a more distributed environment, the statement 'You will get this message at least once' becomes a helpful mantra, as it helps to avoid the pitfalls of the network.
Hope that helps
-d
I was having a discussion with a friend about MassTransit about the purpose of the subscription (pubsub) service in MT, and I thought I would address the issue here.
Basically, the subscription service is what allows us to 'publish' messages. At a high level, before the bus does a publish it consults with the subscription service to see if there are any susbscribers. If there are, then each subscriber gets a copy of the message. Otherwise, nothing is sent.
At a lower level there is a subscription client that cache's the subscriptions locally to the service, and it is this cache that is consulted pre-publish. The cache is kept up-to-date via messaging (whoda thunk) so that there is a minimal amount of polling.
Therefore, if the subscription service (and the client) is not running, then nothing will be sent. As you can see its a pretty important part of the system. :)
Ok, so that wasn't as awesome as I had hoped but hopefully it helps.
-d
What a crazy weekend. I am glad I got home with some time to rest, because we ran non-stop the whole time. Whether we were exploring the island of Manhattan or talking philosophical discussions about OMeta# and hard disk buffers we were having a ball.
I have learned about OMeta# and DotLucene, going to have to check these projects out.
Went through the MassTransit code base with Oren, that was fun!!
Decided, in honor of the trip, I am going to rename MassTransit.Dashboard to MassTransit.Authority in honor of the excellent job they did running the public transportation system. :)
We ate at several excellent restaurants the most notable being 'Republic' (thanks Laribee!), as well as the view (not the service) from Harbor Lights.
I just want to give a shout out to the people at MidWest who actually studiied queing theory, and have people board the plan in reverse order. Bravo!
-d
Hello True Believers,
I am excited to announce the release of the 0.3 Mass Transit has occurred and is available on the site.
So what's been going on the last 2 months? Well, first Chris and I each took a much needed break after the 0.2 release which saw a lot of API changes as we took what we learning from real work and incorporating it into the project. Once the batteries recharged, we (and by we I mean Chris) started to work on the next release. We have added the initial support for Sagas (think workflows) and we added the initial support for a Grid. Of course, both of these are very cool features, that will continue to mature over the coming releases, but the real benefit was in how adding these features made us take a step back and reevaluate how we have composed the projects. We continue to find ways to make the core project increasingly extensible without modifying the core. This is important for the long term health of the project as we will need to continue to add features and functionality, but we want to keep things as lean as possible.
We have also spent quite a bit of time refactoring and improving the 'host' concept. The host project is a way to host your services, which eliminates a lot of boiler plate code. Several of the samples are using this to host the work, so if you want to see how they work that is the best area (its not exactly obvious yet, and I hope to fix that by 0.4).
Another thing that has been a huge benefit, is that Chris went through and started to rewrite a lot of our unit tests using more of a Spec / BDD style. In the process of doing this uncovered some small bugs which are now cleaned up, and we won't ever see them again. :). The tests should be quite a bit better now, but they still need a lot of work as they have grown organically for quite a while now.
We have also started to run NDepend on our builds which, when we get it tuned, should provide a way for us to make sure our code is adhering to certain quality standards as well.
Well that's about all that I can remember right now. If you get some time to check the project out make sure to look in the Samples folder and look at the WinFormSample.
-d
A friend of mine started a blog called
make stuff with your kid
If you have kids and want to get them back into the physical world this blog should provide some interesting activities. Heck, he's talking about making all kinds of stuff and then showing us noobs how to do it as well!
Cool stuff,
-d
Please note that this is pre-AutoMap which I haven't dived into yet, but I thought it would be nice to share none-the-less.
public class LeadMap :
ClassMap
{
public LeadMap()
{
Id(o => o.Id);
Map(o => o.CreatedOn);
Component(o => o.Company,
x =>
{
x.Map(m => m.Name);
x.Map(m => m.Address);
x.Map(m => m.Website);
x.Map(m => m.Telephone);
});
Component(o => o.Contact,
x =>
{
x.Map(m => m.Name);
x.Map(m => m.Telephone);
x.Map(m => m.Email);
x.Map(m => m.Title);
});
Component(o => o.Survey,
x =>
{
x.Map(m => m.DoTheyWantToBeAnAgent);
x.Map(m => m.WhatTypeOfAgentDoTheyWantToBe);
x.Map(m => m.FoundUsVia);
x.Map(m => m.InBizSector);
x.Map(m => m.WantsAFollowUpCall);
x.Map(m => m.WantsToKnowAboutMainProducts);
x.Map(m => m.WantsToKnowAboutOtherProducts);
x.Map(m => m.WantsToKnowAboutPricing);
});
HasMany(o => o.InterestedIn)
.Component(x=> {
x.TableName = "Lead_Items";
x.Map(m => m.ItemId);
}
).AsSet();
}
}
Just a quick post about FluentNHibernate. Its such a simple project that is really going to take NHibernate to a new level. The basics are there, and although the AutoMap stuff has just been committed I have already found a feature that has made it a must have: fluent configuration.
var properties = PostgreSQLConfiguration
.PostgreSQL82
.ConnectionString.Is("User ID=postgres;Password=xxx;Host=localhost;Port=5432;Database=test;")
.ToProperties();
var cfg = new Configuration()
.AddProperties(properties);
Awesome!
I am working on domain where I need to support the ability to translate content. Such as a product description. I am imagining that the domain model might look something like:
product.Description = "Widget";
product.Translation[Language.English].Description = "Tegdiw";
or
product.Description = "widget";
product.Description[Language.English] = "tegdiw";
or
IProduct product = repository.Get(1, English);
product.Description = "wow";
IProduct productZh = repository.Get(1, Chinese);
productZh.Description = "waw";
Of the three I have presented here, I think I like number one the best. I would say that I like it the most because I have done this model before and it seemed to work well, I am just wondering how much I really care that it forces me to have 2 tables per entity that I want translations for (Product and ProductTranslations). Really that's not that bad I guess. Anyways, I wanted to put my thoughts out there to see if anyone else had some better ideas. :)