Agatha Vs NServiceBus?
Posted by Davy Brion on January 26th, 2010
Ever since i open sourced Agatha, i’ve gotten questions from people who are wondering whether they should use Agatha or NServiceBus. I’ve also gotten questions about things that people wanted to do with Agatha but that aren’t really supported. And i’ve also noticed that people were coming to my site with search keywords like “agatha vs nservicebus”. The thing is, they are hardly comparable.
Agatha is a Request/Response Service Layer framework. It basically supports synchronous and asynchronous Request/Response style communication and tries to make it as easy as possible to write a service layer for that type of communication. Apart from being easy to use, it also encourages a clean implementation of your service layer and a way to minimize the repetitiveness of cross-cutting concerns. It also enables you to get better performance than with typical Remote Procedure Call or Remote Method Invocation style service layers because it will try to minimize roundtrips by batching requests and responses together. In the next release, it will also offer a caching layer so certain requests (depending on how you set it up) don’t need to be processed and cached responses can simply be returned. There’s also support for one-way requests (or fire-and-forget requests) but it has the same downsides as one-way requests with typical WCF services have. That’s pretty much all it does. That’s probably all it’ll ever do. In short, it’s just an upgrade over your typical WCF services.
NServiceBus on the other hand also does Request/Response, but that’s just one of the things it can do. Again, Agatha is essentially an RPC or RMI framework whereas NServiceBus is built on top of one-way messaging technology. This allows for much more possibilities when it comes to communicating between different applications or different parts or processes within the same application boundary. A great overview of those possibilities can be found here. Because it is based on messaging, there are a lot of benefits that you can get from NServiceBus that you’ll probably never get from Agatha. For one, the ‘Store & Forward’ messaging model from NServiceBus might seem similar to Agatha’s one-way requests on first sight, but there are some very important differences. If you send a fire-and-forget request with Agatha, and the service is currently down, then that request is essentially lost. With NServiceBus, the message is stored in a message queue and it will be processed when the target of the fire-and-forget message comes up again. From a reliability point of view, that’s obviously a tremendous improvement over what Agatha can offer you. Another area where NServiceBus truly shines (IMO) is in its Publish/Subscribe implementation. Some people have asked me if i’ll ever provide something like that in Agatha and the answer has always been ‘no’. For one, it doesn’t fit into what Agatha tries to do and i don’t see the point in implementing it if a better implementation is available already in another project. There’s plenty more interesting things in NServiceBus to deal with more advanced scenarios, which you’ll have to find out about on your own
So which one is more suitable for you or your applications? As with every technology choice, it depends. Agatha is great for most typical business applications. If you need to communicate between one or more different clients (with different i don’t mean multiple instances but different types of clients like a web app, a silverlight client and/or a WPF client) and one service (you can obviously use it with more than one service as well if you want to) on an application server which encapsulates your business layer then it is a very attractive solution, as long as you don’t need the superior reliability that NServiceBus can offer you. With superior reliability i particularly mean the ability to still process received messages once the service layer comes back up after having been unavailable. In my experience, most business applications don’t really need that, since most of those applications are entirely unusable if the service they depend on is down. In short, if all the possible downsides of using a WCF service layer are not an issue for your project, then Agatha will be a great fit.
If however, you need to maximize reliability, performance and general robustness of a critical enterprise application, then NServiceBus will definitely be a much better choice. If you’re dealing with many distributed parts, NServiceBus will also make things much easier for you than Agatha (or any other WCF service layer for that matter) will. And obviously, if you want to integrate multiple applications while reducing coupling between applications as much as possible, NServiceBus will also be a much better fit than Agatha. With NServiceBus, you’d only need to share an assembly containing the types of the messages. With Agatha, you either need to share an assembly with shared request/response types or use proxies for them and you would also have to know about the other applications since you’d need to access their services directly. This can get quite ugly pretty fast.
And in some cases, you can just use both of them at the same time. At work we have two projects that use Agatha for all of their internal communication within their own application boundary, yet they use NServiceBus to notify each other of certain events. Neither of the applications knows about the existence of the other… the only thing they share is one assembly with some shared message types. We’ve also started working on a new platform where each application in the platform will use Agatha for all of the communication within their own application boundary (since they’re all typical silverlight clients backed by a WCF service style applications) but they will use NServiceBus for every kind of communication that goes outside of the application boundary.
As with many things, it’s just a matter of choosing the right tool for the right job. Hopefully, this post will help some of you make that decision should you need to make it in the future
January 26th, 2010 at 11:45 pm
Nice post Davy, agree with everything you said. Indeed, it makes total sense to use Agatha as Service Layer in front of your backend that is using NSB. Obviously, NSB is not just useful for inter-application communication, but also in intra-application communication (cfr CQRS à la Udi, or à la G. Young for more advanced needs). Now, here is a feature request for vNext of Agatha :
(and that would be the adult version of RIA Services lol).
Add support for interface-based messages like NSB supports it, so that, in a CQRS architecture, assemblies containing command & query messages can be shared all the way down from the UI to the Backend
January 27th, 2010 at 8:41 am
@Steve
could you be a bit more specific about what exactly it is you want?
January 27th, 2010 at 10:03 am
Being able to define messages as simple interfaces e.g. :
public interface MyCommand
{
int SomeId { get; set; }
string SomeString { get; set; }
}
Then, when sending a message:
IAsyncRequestDispatcher dispatcher;
dispatcher.Add(msg => {
msg.SomeId = 1;
msg.SomeString = “TestMessage”;
});
In this case, the dispatcher would recognize the fact that the message type is an interface, generates a simple (serializable) class implementing this interface, call the constructor Action that was passed as argument and then send the message …
=> Check the IMessageCreator interface in NSB
This feature is really useful for versionning of message contracts as well as for enforcing the fact that there shouldn’t be any funky logic / code in message types.
January 27th, 2010 at 10:11 am
@Steve
it’s interesting, but i’m not sure if it would be possible… in order to send the generated serializable class through the DataContractSerializer, it has to be added as a KnownType both client-side and server-side… if the request type is generated at runtime, it’s gonna be pretty tricky to get it accross the wire properly
January 27th, 2010 at 11:21 am
Question is … should Agatha stick to the DataContractSerializer if you know you have Agatha at client & server-side ? You might well use a custom serializer derived from the NDCS, that would allow you to go past the limitations of the standard DCS.
January 27th, 2010 at 11:22 am
@Steve
maybe we should take this discussion to the agatha discussion group
January 29th, 2010 at 2:00 pm
>It basically supports synchronous and asynchronous Request/Response style communication
Is req/response not always synchronous?
January 29th, 2010 at 2:05 pm
according to some definitions, yes
but if a client can expect a response to its request to a service, i’d consider that request/response whether or not the call was made synchronously or asynchronously
in silverlight, you can’t make synchronous service calls for instance… yet most people are definitely using request/response style communication in those projects