Writing good software is a thing of beauty and a thing of beauty is a joy forever. What constitutes good software? Code that looks good? Three lines of code as opposed to lines and lines of code?
There was a time, I was blissfully unaware of a fundamental coupling in code called, “Temporal Coupling”. In my mind, being Service Oriented was JBOWS. Just a bunch of WCF/Web services, that call each other to fulfill something. These services were grouped into Capability Services, Activity Services, and Entity Services. In my mind, Services equaled WCF. And yes, though WCF offers a whole bunch of bindings. I had stuck to using Tcp. I was doing full fledged synchronous blocking request response without being aware of consequences.
I was designing a thing of beauty. The software was going to be being oriented into these blocks of services! Calling these services was simple too! As MSDN samples show, it was just three simple steps:
//Step 1: Create an instance of the WCF proxy. CalculatorClient client = new CalculatorClient(); // Step 2: Call the service operations. Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; double result = client.Add(value1, value2); //Step 3: Closing the client gracefully closes the connection and cleans up resources. client.Close();
The first problem I ran into was timeout exceptions, and the problems didn’t end there. Needless to say, it was far from beautiful and the devil is always in the details. Those three lines of code that looked beautiful hid a whole lot of things that I needed to make explicit in my design.
What if the service was not up? What if the client called the method and the service operation is executing and the operation timed out on the client side, but the operation completed on the server side? What if this was a web service in a land far far away? Do I need to retry the failed operation? Can I safely retry the operation?
My questions led to the first answers, led to the fact that these so called services were temporally coupled. What does that mean? Well, it means that one service cannot complete its function if the other service is not around to perform what it’s asked to do. So, if Service A calls Service B, and Service B is down, well good luck to the million dollar order that is trying to be placed into the system. No Bueno!
So, this whole idea of the activity service calling a capability service calling another service tumbled quickly into the abyss. More thought went into, how can these services be on their own without being dependent on each other to fulfill these capabilities and a design pattern that has been around forever emerged into sight. Event Driven Architecture and the Publish-Subscribe pattern.
Enter a different way of thinking
Well the real world works on events. A low battery event on your computer makes you react and plug in the power source when the event occurs. You react to events and perform certain actions when they occur. And yet why is that we write code on a command-control basis? Our programs mostly tend to, call method, perform action, retrieve more information, do this do that as if nothing else can go around these actions.
What if we turned that around and made software react to events? An order placed event. The billing system can react to it and charge the customer and publish CustomerCharged event. The shipping system can then react to this event and ship the item. There is no service calling service, instead a loosely coupled model where services can be truly autonomous emerges.
Software “talking” to software via messages to convey a certain something happened. These messages being durable, i.e. in case of something bad happens, they can be still around, so when the process is restarted, the service is aware of “I still need to process this message”. Messaging makes things explicit of all the things, as a software person I need to consider and account for, exactly what those three steps of code was masking.
How can I build this awesome pub/sub as the backbone for the software I write?
Juval Lowy’s WCF book has a whole appendix worth 33 pages that describes, how you can build your own pub/sub system using WCF. All I can say is, May the force be with you. To start anything is easy, but to build it and build it right takes time. And the pressure is on you to make sure that this works well, and you’ve taken care of every teeny tiny detail, since this will be a fundamental piece of the system. The last thing you want is events gone AWOL and the CEO watching you while you are trying to frantically debug your system! Talk about pressure!
There is a much easier way!
When I was on this quest to find a framework that can help me build software in a loosely coupled, event driven manner, my path crossed with NServiceBus.
NServiceBus is a light weight framework has been around for a long while and offers a robust and a relatively simple way of using pub/sub in your software. You can have pub/sub in 5 minutes, no kidding. I’ve haven’t looked back since and I don’t miss WCF much! My experience with NServiceBus has been fantastic. I could now focus on my business problem and not worry about the intricacy of how the underlying messages get transported and the infrastructure aspect. IJW (It just works!) and yes, Atlantis does exist!
When you leave behind RPC request response blocking calls and start thinking in terms of event driven programming and how messaging and good architecture makes your software more reliable and autonomous, I say, you’ve arrived in the land of beautiful software and yes, Keats was right. A thing of beauty is a joy forever.