Saturday, February 01, 2003

Optimistic, Pessimistic and Realistic Invocations

It has been stated that one of the primary advantages of web services is loose coupling. I believe that web services have the ability to provide loose coupling, but it is something that must be achieved; it isn't granted.

An example of this is in the web service invocation model. Most people are aware that web services fall into the SOA model, thus they have a consumer, producer and directory. The idea is that a consumer will look in a directory to find a producer then use this information to call the producer. This can provide different values such as:
- the ability to find competing service providers (trading partner style)
- the ability to find multiple, redundant services (same service, different boxes)
- the ability to abstract the caller from backward compatible revisions in the service (such as a change in physical location of the service provider)

It is this last example where most people start shouting that web services enable loose coupling. Yet, what I have found after reviewing sample web service code is that most people don't actually design their software to take advantage of this feature. I've created a few terms that should help articulate the point:

Optimistic Invocation
Most of the sample source that I have seen does "optimistic invocation". That is, the client makes the assumption that it already knows where the service provider is (surely nothing will ever change in the production environment...)
Thus, you see code like this (excuse my pseudo):
Proxy MyProxy = new Proxy ("http://www.HardCodedLocation.com/myservice/");
MyProxy.invoke(someOperation, blah blah blah);


Here, the programmer is an optimist. They assume to know where the service is located and call it. This is quick (no directory lookup) and simple (no directory lookup).

Pessimistic Invocation
Another method of calling some service is to assume that we know nothing..
Directory MyDirectory = new Directory();
Proxy MyProxy = new Proxy();
MyProxy = MyDirectory.lookup("some service description..."
MyProxy.invoke(someOperation, blah blah blah);


Here, the programmer checks the directory before each call... making sure that the client has the latest information on service providers. This adds a few lines of code and increases the processing time by adding a directory lookup to each call.

Realistic Invocation
The Realistic Invocation model is designed to find a happy medium between 'optimistic' and 'pessimistic". The idea is to start out optimistic and if it doesn't work to fail over to pessimistic:
Proxy MyProxy = new Proxy ("http://www.HardCodedLocation.com/myservice/");
try {
// give the optimistic way a try...
MyProxy.invoke(someOperation, blah blah blah); }
catch (Exception e)
{
// if optimistic failed, switch to pessimistic
Directory MyDirectory = new Directory();
Proxy MyProxy = new Proxy();
MyProxy = MyDirectory.lookup("some service description..."
MyProxy.invoke(someOperation, blah blah blah);
}


Wow... 'Realistic Invocation' just turned into a whole bunch of code. Well, that should be easy enough to fix. You can either turn this model into a helper function or apply an aspect across the service calls. The real point is that optimistic invocation doesn't help much with loose coupling... pessimistic invocation usually isn't realistic from a performance standpoint, thus using a realistic model (with helper functions) gives you a simple, effective method of doing distributed calls while preserving the loosely coupled model.


No comments: