Archive for the 'SOA' Category
Subjugating Temporal anomalies to satisfy software’s Prime Directive
Having just read one of Howard Dierking’s latest posts regarding how we reason about time when it comes to software, I am reminded about the benefits that one way messaging and publish / subscribe can bring to the table. It stands to reason that we all want our code to execute faster and our applications to respond to their users in a timely fashion; ‘slow’ is not a word users or developers alike want to hear when discussing or describing their systems. Howard’s post is a discussion that came out of his reading a book by Steven Seow titled “Designing and Engineering Time: The Psychology of Time Perception in Software”. I personally haven’t read the book however my interest in doing so has certainly been raised. I am interested here in turning the architectural spotlight onto the strategies for managing time.
Howard includes the following table in his post (the first two columns), demonstrating how perceptions of time in software / human interaction can be managed effectively. As my mind turned to thinking about publish subscribe and one way messaging I decided to add another column to this table clarify my thinking.
| Performance Dimension | Management Strategy | One Way Messaging Pub / Sub Strategy |
| Actual Performance – the precise time durations for completing a task | Operational Management – purely technical strategy (e.g. change the way it works to make it faster) | Let’s push aside algorithmic tweaking designed to speed up computation for just a moment and consider this aspect from a scaling / throughput perspective. In systems that attempt to address this through stateless web services, the strategy is one of scaling out the web servers. If we bring durable queuing into the focus then we can rather more cheaply apply divide and conquer, with patterns such as ‘competing consumer’. In terms of NServiceBus the Distributor is an excellent choice here. Again this is looking at it from an architectural viewpoint. |
| Perceived Performance – the approximate duration for completing a task as experienced by the user | Perception Management – make the task feel like it takes less time (examples include distractions, progress indicators, etc.) | Sending commands or messages to the server for processing and distract the user by maintaining UI state as though the command had been processed. One example is showing blog comments to the submitting user only, whilst waiting for the moderator to approve it. |
| User Tolerance – based on expectations, the approximate duration threshold where anything beyond will be considered slow by a user | Tolerance Management – focus on making users more tolerant of a longer duration when it cannot be shortened or “disguised” | Initial immediate response followed by a subsequent response via a different channel than that sent the message / request. Examples such as Amazon purchases that provide an immediate response and then provides confirmation email. |
In request / response systems, often the focus goes into that described in row 1 column 2 above; that is we tend to narrow in on speeding up our code, substituting for faster implementation technologies or even scaling up our hardware. In the case of stateless Web Services it’s also common to scale out the web servers. With one way messaging and NServiceBus we can increase our throughput and speed (both real and perceived) by scaling out our services and what’s more this can be achieved relatively cheaply with commodity hardware.
It’s also worth noting that the effects of implementing durable queues play’s into the Reliability aspect of the system and when those queues are placed physically adjacent with task based smart client applications that both send and receive messages, then it’s possible to create the perception that work is submitted immediately; potentially it may be repudiated later if there is something wrong with the submission itself. Maintaining a low number of these repudiated work submissions (command / messages) can increase the tolerance levels and the perceived improvement in speed in getting through the work itself.
No commentsSOA and Messages - What’s in a name
So the question is what’s in a name, when it comes to considering messages of the SOA variety, or to be more precise in a messaging system? Well I guess it depends on who you ask doesn’t it and let’s for argument sake extend the idea of the ‘who’ to include the implementing technologies of the day and any of their accompanying GBE (guidance by example). Consider this fragment of WCF code that declares the signature of a service. The example comes from the MSDN stock trader example application.
Listing 1.0
[ServiceContract(Name = "OrderProcessorService", Namespace = "http://Trade.TraderOrderHost")] public interface IOrderProcessor { [OperationContract(Action = "SubmitOrderTransactedQueue", IsOneWay = true)] void SubmitOrderTransactedQueue(OrderDataModel order); [OperationContract(Action = "SubmitOrder", IsOneWay = true)] void SubmitOrder(OrderDataModel order); }
Self Evident?
The first thing I would like to highlight about this example is the name of the service itself, it has a very generic sounding name that does not say a lot about the domain in which we are processing orders. True enough there is some clue in the WCF ServiceContract attribute property assignments but is that sufficient? The next thing I want to point out is that when an order is submitted with the intent that it should be stored in a transactional queue, the service operation responsible has been named specifically to speak to that intent (of storing in a queue). The fact that the message is stored in a queue is an implementation detail and on the surface it appears has absolutely no association to the business context of the operation, which is to “submit an order”. If on the other hand there is a business requirement to have *certain* messages stored in a durable transactional queue, we should probably be taking those business considerations into account with respect to naming the message handler (operation). Making some assumptions, perhaps this would a better naming scheme for that scenario:
Listing 2.0
[OperationContract(Action = "SubmitStrategicCustomerOrder", IsOneWay = true)] void SubmitStrategicCustomerOrder(OrderDataModel order);
Next up lets focus on the name of the operations single argument OrderDataModel, which is significant for a couple of reasons. Firstly, is this operator really a model – its name says it is? Certainly not if we want to hold it up to the DDD definition, it carries no behaviour with it – it’s just data, information about the order that is being “submitted”. So is OrderDataModel a DTO? If feels like a DTO doesn’t it, thus we should ask what is the message? I am not going to get too heavily into a discussion of what constitutes the ‘message’ when it comes to SOAP services, only to reflect that many consider it to be the combination of the operations and their operators, whilst some consider it to be just the operators alone and others don’t speak of messages at all and consider an operations arguments as nothing more than DTO’s.
Let’s take a different approach to this problem, what if we were to name the contract for this service IProcessOrders and include handlers (methods) for cancelling the order amongst other things.
Listing 3.0
public class StockTradeOrderService : IProcessStockTradeOrders { public void Submit(OrderMessage order) { //….etc } public void Cancel(OrderMessage order) { //….etc } }
I cant say it feels right to me yet but gradually I do feel as though the names of this service and the intent expressed by it’s message handlers are becoming somewhat more reflective of the business problem it attempting to solve, making the code easier to reason about.
Lets have a look at how I might go about specifying the contract and implementation for such a service using NServiceBus.
Listing 4.0
public class SubmitOrderMessageHandler : IMessageHandler<SubmitOrderMessage> { public IBus Bus { get; set; } public void Handle(SubmitOrderMessage message) { OrderSubmittedResponseMessage response = new OrderSubmittedResponseMessage (); //more processing to act on the order message this.Bus.Reply(response); } }
What about cancelling the order then?
Listing 5.0
public class CancelOrderMessageHandler : IMessageHandler<CancelOrderMessage> { public IBus Bus { get; set; } public void Handle(CancelOrderMessage) { //processing } }
Structural differences aside, I still feel strange about the whole SubmitOrder aspect to the naming as it stands, it still feels a tad too generic for my liking. To be fair, an order service might not be something that would be modelled with singular discrete message handlers like this, perhaps it would better be modelled as a Saga (think persisted workflow), just as it is in the NServiceBus samples, but that’s not the focus here so we wont dwell on that either.
The SubmitOrderMessageHandler demonstrated above, handles messages of the type SubmitOrderMessage, where the IMessageHandler provides us (via the strategy pattern) a Handle<T> method, where T is the message type and the Handle methods body has the express purpose of implementing the logic for handling the message.
By now you can probably see where this all going? The “data” contained in the SubmitOrderMessage is certainly different to the data contained in the CancelOrderMessage and if we shift our focus now back to the WCF stock trader example to consider the OrderDataModel (the argument to the SubmitOrder method) then its evident that the message carries some data used by the generic handler to examine more closely exactly what the intent is (beyond the ‘submission’ of the order). Again this is not plainly clear from the name of the message alone. The OrderDataModel data contract has a property (of string) called ‘orderType’ and looking at the component that has the responsibility of processing orders, we can see that it checks the value of the ‘orderType’ to discern whether or not to process the order to BUY or SELL.
Listing 6.0
if (order.orderType == StockTraderUtility.ORDER_TYPE_BUY) { //…do some work for a buy order } else if (order.orderType == StockTraderUtility.ORDER_TYPE_SELL) { //…do some work for a sell order }
Generic in the name of Reuse?
In an article by Thomas Erl, he speaks of more ‘generic’ naming schemes when it comes to ‘utility services’ but I don’t have any generic ‘business’ operations because the domain in which I work is not typically generic. Therefore when I put on my AOP hat and start thinking about some of the cross cutting concerns that crop up in any number of business domains, such as the ubiquitous logging for example, shouldn’t I reasonably be expected to relax my naming sensibility? But that’s not really the problem under discussion here is it.
Lets take the code now from listing’s 4.0 and 5.0 and propose a new approach to the model suggested by the Stock Trader for the submission of buying and selling trades:
public class SubmitBuyOrderMessageHandler : IMessageHandler<BuyOrderMessage> { public IBus Bus { get; set; } public void Handle(BuyOrderMessage) { BuyOrderResponseMessage response = new BuyOrderResponseMessage (); //more processing to act on the order message this.Bus.Reply(response); } } public class SubmitSellOrderMessageHandler : IMessageHandler<SellOrderMessage> { public IBus Bus { get; set; } public void Handle(SellOrderMessage) { SellOrderResponseMessage response = new SellOrderResponseMessage(); //more processing to act on the order message this.Bus.Reply(response); } }
Messages and their names should map closely to business events modelled by the system; business events as such should have their names represented in non generic terms with more focus on their explicit context. I want to build self evident, self describing business systems where things like implementation details should certainly not figure in the naming of messages or their handlers, that’s something for ‘other’ documentation.
1 commentUpdate on SOA / DDD Course with Udi Dahan in Melbourne Australia
Due to a rescheduling of this course there are now 3 seats available. If you missed out last time, registrations have now reopened for this limited number of seats. Please follow this link to register. The new date for the course is January 18th – 22nd 2010.
1 comment







