søndag den 25. september 2011
New version of SAPIT available
I have just uploaded a cleaned up version of SAPIT (sapit.codeplex.com) for anyone to play with. There are a few breaking changes to be aware of: I have deleted the parametrized attribute constructors, so they can only be called with named parameters. I think this is more readabled since some of the attributes take 4 parameters, and now you're forced to name each parameter.
If you hang out in the Copenhagen area, you can come and hear me give a talk on AOP and SAPIT at the Copenhagen .NET User Group (CNUG) event on October 4th: http://www.eventbrite.com/event/2105414351/eorg
Also, I'm working on a few extra blog entries about books I've been reading lately ... stay tuned :-)
onsdag den 16. februar 2011
On adding support for StructureMap to Sapit
I got a request for adding support for StructureMap to Sapit, and being the challenge-loving type, of course I set out to implement it. I thought, how hard could it be? As it turned out, quite hard!
What separates StructureMap from Unity, Windsor and PostSharp that Sapit already supports, is that StructureMap does not by itself provide a means to do method interception, which is what Sapit is all about. To apply for instance caching to a method, Sapit needs to intercept the calls to the method, invoke some caching logic, let the method call proceed, and then pick up the return value, cache it and return it to the caller. Without a means to intercept the method call, Sapit has no value.
So what to do? Well, after trying to find a way to intercept the call by manually generating a generic proxy (via the .NET 4 DynamicObject class), I got the idea to use Castle DynamicProxy instead. A lot of third party libraries use DynamicProxy under the covers, because it really is a great tool to gain full control over your objects.
However, so far I've not been able to get it to do, what I want. What I want is to use DynamicProxy within a StructureMap type instantiation interceptor to generate a dynamic proxy object with all the right features. The proxy object should wrap the "real" object, expose the same exact interfac as the real object, and have the same set of attributes applied to each method. Until now, I can make DynamicProxy generate a proxy object, but it does not expose the right interface.
If anybody out there has some documentation on how to use DynamicProxy, or perhaps some sample code demonstrating how to use it, I would really appreciate a hint. Meanwhile I will continue to try implementing StructureMap support in Sapit, and I will keep you informed on any progress.
torsdag den 20. januar 2011
Sapit - now with Retry functionality added
New functionality
I have just checked in an updated version of Sapit (Codeplex). Included now is the Retry attribute, that automatically retries failed method calls.
How to use Sapit
I figured i was about time I threw in a little documentation on how to apply Sapit to your code. The table below describes each of the 5 attributes and their parameters.
Atrtibute | Parameter | Meaning |
---|---|---|
Cache | Caches the result of the method call. | |
CacheSeconds | The number of seconds to cache the result | |
CircuitBreaker | Monitors the method for exceptions, and if too many consecutive calls fails, it shuts off the method for a period of time. | |
MaxConsecutive-Failures | The maximum number of consecutive failures before the method is shut off | |
ShutOffPeriodSeconds | The number of seconds to leave the method shut off | |
BehaviorWhen-ShutOff | How to react to method calls when shut off, return af default value or throw an exception | |
ShutOffReturnValue | The default value (or exception message) to return | |
ResponseTimeThrottle | Throttles away calls to a method when the response time rises above a given threshold | |
ThrottleThreshold-Milliseconds | The maximum response time before throttling sets in | |
SkipCallsWhen-Throttling | How many calls to throttle away when throttling | |
BehaviorWhen-Throttling | How to react to method calls when throttling, return af default value or throw an exception | |
ThrottleReturnValue | Caches the result of the method callThe default value (or exception message) to return | |
Retry | Retries failed method calls up to a given number of times before giving up. | |
TimesToRetry | The maximum number of times to retry the metod call before giving up | |
Timeout | Aborts method calls taking longer than a given limit. | |
TimeoutMilliseconds | The number of milliseconds before aborting the method call |
Each of the above attributes are defined in each of the assemblies Sapit.PostSharp.dll, Sapit.Unity.dll and Sapit.Windsor.dll, and they functionality in the assembly Sapit.dll. This means, that when you wish to include Sapit in your project, you only need to add a reference to Sapit.dll and to Sapit.<your IoC>.dll, where <your IoC> is your IoC of choice, PostSharp, Unity or Windsor. After adding these two references, you just apply the appropriate attributes to the methods you want. The only thing left is to configure your IoC (this is only true of Unity and Windsor, since PostSharp simply alters the MSIL after compilation).
Configure your IoC to use Sapit
Unity
Use the following code to configure Unity to use Sapit, where IMyInterface is the interface for the class MyImplementation:IUnityContainer container = new UnityContainer();
ServiceProvider.IUC = container;
container.AddNewExtension<Interception>();
container.RegisterType<IMyInterface, MyImplementation>();
container.Configure<Interception>().SetInterceptorFor<IMyInterface>(new TransparentProxyInterceptor());
Windsor
Use the following code to configure Windsor to use Sapit, where IMyInterface is the interface for the class MyImplementation:WindsorContainer ioc = new WindsorContainer();
ServiceProvider.IWC = ioc;
ioc.Register(Component.For<CacheInterceptor<string>>());
ioc.Register(Component.For<CircuitBreakerInterceptor>());
ioc.Register(Component.For<ResponseTimeThrottleInterceptor>());
ioc.Register(Component.For<TimeoutInterceptor>());
ioc.Register(Component.For<RetryInterceptor>());
ioc.Register(Component.For<IMyInterface>()
.ImplementedBy<MyImplementation>()
.Interceptors<CacheInterceptor<string>>()
.Interceptors<CircuitBreakerInterceptor>()
.Interceptors<ResponseTimeThrottleInterceptor>()
.Interceptors<TimeoutInterceptor>()
.Interceptors<RetryInterceptor>());
Feedback?
Please let me know if you find bugs in the code, errors in the above documentation, or if there is something unclear.
Also, I am very open to suggestions and requests for improvements and more features.
Enjoy :-)
lørdag den 15. januar 2011
How the deal with external systems?
The problem
When developing solutions today, we almost always have to connect to external systems. These connections come in all shapes and sizes, from accessing a file system or connecting to a database, to transferring files to or from an FTP server, or to call a web service or an enterprise service bus.
When connecting to external systems, we are exposing our own system to risks. And I am not talking about security risks like vira, malware, evil hackers and the likes, but I am talking about the risks of performance degradation, scalability issues, dependencies upon the status of the external systems, poor user experience and more. If we are not very careful when we design our solutions, all bets are off when the external systems slow down, become unstable or even shut down. If we fail to take such situations under consideration, the state of the external system dependencies dictate the state of our system – if just one external system is down or unstable, our system will be down or unstable too. So when building large systems with many external dependencies, making sure our system keeps running, can become a real nightmare.
Ways to deal with external dependencies
In his excellent book “Release IT!”, Michael T. Nygard writes a lot of good advice on how to deal with external dependencies. He describes several patterns and techniques that are useful for lowering the risks of external systems damaging the performance and stability of our system. Other great minds have further elaborated on the topic in books, blogs and presentations, and we now have an arsenal of patterns and techniques at our disposal. I will briefly sum up four of these here:
Caching is a technique where you hold on to a result from a call to an external system for a while, and reuse this result instead of making subsequent calls to the external system.
Circuit Breaker is a pattern where you keep tabs on whether the calls to an external system fail or succeed. If the calls begin to fail, you register the external system as being down and stop making calls to the external system. After a while you try passing a few calls on to the external system to see if it is up and running again.
Response Time Throttling is a technique where you monitor the time each call to an external system takes, and if the response time rises above a certain threshold, you filter off some of the calls to the external system. Thereby your system does not put additional strain on the external system, and hopefully the external system will eventually come up to speed again.
Timeout is a technique where you stop waiting for response from an external system when a certain response time threshold is reached. You basically abandon your request and return an error message back to the caller saying that the timeout has expired.
The standard solution
Usually some or all of the above patterns and techniques are being built into our systems, but very often people are reinventing the wheel over and over again. There are so many different ways to include these techniques in the interaction with external systems, and the result of this is more often than not a bit messy. As an example, take a look at the following code:
public class ItemServiceGateway
{
private static Dictionary<int, Tuple<List<Item>, DateTime>> _Cache = new Dictionary<int, Tuple<List<Item>, DateTime>>();
private static int _SecondsToCacheResult = 30;
public List<Item> GetItemsInCategory(int categoryId)
{
List<Item> results = GetResultsFromCache(categoryId);
if (results != null)
{
return results;
}
else
{
results = GetResultsFromExternalSystem(categoryId);
AddResultsToCache(categoryId, results);
return results;
}
}
private List<Item> GetResultsFromCache(int categoryId)
{
if (_Cache.ContainsKey(categoryId))
{
if (_Cache[categoryId].Item2.AddSeconds(_SecondsToCacheResult) > DateTime.Now)
{
return _Cache[categoryId].Item1;
}
else
{
_Cache.Remove(categoryId);
return null;
}
}
else
{
return null;
}
}
private List<Item> GetResultsFromExternalSystem(int categoryId)
{
List<Item> results = null;
// Make call to external system to get the results.
return results;
}
private void AddResultsToCache(int categoryId, List<Item> results)
{
if (_Cache.ContainsKey(categoryId))
{
_Cache.Remove(categoryId);
}
_Cache.Add(categoryId, new Tuple<List<Item>, DateTime>(results, DateTime.Now));
}
}
The above code is a simplified but very realistic way of implementing a cache around a single call to an external system. Now multiply the above code by the number of external system calls your system makes … And yes, I am aware that this implementation is not thread safe, but this just amplifies my point: It takes a lot of time and effort to include these techniques and to make them work correctly and robust.
The problems with the standard solution
From the above code it is obvious that implementing your own cache for every external system call is not a very efficient way to go. Your system will end up being 90% plumbing code and 10% actual value-adding code. The development costs will be very high, the maintenance costs will be very high, and the potential for errors will be very high.
One of the biggest problems, in my opinion anyway, is that the above code obscures the intent of the code. You can’t really see the forest for the trees. In fact, the call to the external system is buried in one of the private helper methods, so if will take longer to grasp what really goes on, when a call to GetItemsInCategory is made.
Wouldn’t it be nice, if the code looked something like this instead?
public class ItemServiceGateway
{
[Cache(30)]
public List<Item> GetItemsInCategory(int categoryId)
{
List<Item> results = null;
// Make call to external system to get the results.
return results;
}
}
Well, that is my goal with Sapit!
Sapit to the rescue
I am working in my precious spare time to make the above code work like you would expect it to: Keep a cache of results from the external system, each with a validity period of 30 seconds, and avoid calling the external system, if we already have the results in the cache.
I have built Sapit (Small And Powerful Integration Toolkit) and put it on Codeplex. Included in the source code is a small WinForms project, that demonstrates the use of each of the currently supported features.
Sapit uses Aspect Oriented Programming (AOP) to intercept calls to methods and it includes all four of the above mentioned patterns and techniques, Cache, Circuit Breaker, Response Time Throttle and Timeout. This means that all you have to do to apply, say, the Circuit Breaker pattern to a method, is to apply the following attribute to the method:
[CircuitBreaker(3, 20, Behavior.ThrowException, "Service is down")]
The meanings of the parameters are:
- number of consecutive calls to throw exceptions before we shut off the external system (3 calls),
- the minimum time to wait before we try to call the external system again (20 seconds),
- the behavior when the external system is shut off (throw an exception / return a hard-coded value),
- the value to return or exception message to use when the external system is shut off (“Service is down”)
Sapit is quite self-explanatory, and I have not yet written any documentation for it, but I encourage you to have a look at the source code for the client application included, as it demonstrates how to apply the different attributes.
At the time of writing, Sapit comes with a few limitations.
.NET only – Even though I have a very distant background in the java realm, I have been a .NET developer for a decade now, so Sapit is written in C#.
Thread safety – Sapit does not have this yet. I am working on it currently.
IoC containers – You have to use either Castle Windsor, PostSharp or the Unity Application Block to instantiate the classes you decorate with Sapit attributes, and depending on which IoC container you use the steps to follow differ a bit. It is fairly easy to add support for other IoC containers, so please let me know you use a different one.
Multiple attributes on a single method – I have not tested this at all. Some combinations might work, some might wreak havoc. I am currently working on making Sapit robust in this area.
Next steps
So where do I go from here? Actually, I am hoping for some feedback from you guys. Should I include some more patterns and techniques (which ones?), should I add support for other IoC containers (which ones?), or is Sapit applicable in it’s current form?
I am counting on you guys here!
Please have a look at Sapit, try applying some of the attributes to your own code, and enjoy the cleanliness of code that (hopefully) emerges.
And please, let me know what you think about Sapit, thanks :-)
torsdag den 16. juli 2009
Inspirational reading material
torsdag den 9. juli 2009
How much time do we have?
mandag den 29. juni 2009
Working Effectively with Legacy Code - part 2
- If you control the source code for the parameter classes, you should be able to inherit those classes to make fakes, and just use those during tests.
- If you don't control the source code, you could create a new class, that wraps the parameter object (a proxy if you will), refactor the constructor to use this new class instead of the parameter class, and have it behave differently during test than when in production.
- A third technique could be to use mocking to abstract away the dependencies.
- You could wrap your globals in a static class, that exposes those through static properties, and making the properties behave differently during test than when in production.
- You could try to remove the global all together by injecting the value as a constructor parameter or as a property.