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.

AtrtibuteParameterMeaning
CacheCaches the result of the method call.
CacheSecondsThe number of seconds to cache the result
CircuitBreakerMonitors the method for exceptions, and if too many consecutive calls fails, it shuts off the method for a period of time.
MaxConsecutive-FailuresThe maximum number of consecutive failures before the method is shut off
ShutOffPeriodSecondsThe number of seconds to leave the method shut off
BehaviorWhen-ShutOffHow to react to method calls when shut off, return af default value or throw an exception
ShutOffReturnValueThe default value (or exception message) to return
ResponseTimeThrottleThrottles away calls to a method when the response time rises above a given threshold
ThrottleThreshold-MillisecondsThe maximum response time before throttling sets in
SkipCallsWhen-ThrottlingHow many calls to throttle away when throttling
BehaviorWhen-ThrottlingHow to react to method calls when throttling, return af default value or throw an exception
ThrottleReturnValueCaches the result of the method callThe default value (or exception message) to return
RetryRetries failed method calls up to a given number of times before giving up.
TimesToRetryThe maximum number of times to retry the metod call before giving up
TimeoutAborts method calls taking longer than a given limit.
TimeoutMillisecondsThe 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

I've been reading a lot of books during the last few years ... it feels like I've stumpled upon a huge pile of books, that all seem really important for me to read. Every time I finish a book, the backlog of books in front of me has grown with 3-5 books, that I simply must read. Articles as well are piling up, and it sometimes strikes me, that maybe I am not going to catch up - maybe I am going to have to filter some of the books or articles away ... sigh ...

Anyway, I find all kinds of litterature a great source of inspiration, and therefore I spend a lot of time reading. Surprisingly (to me at least) most of the books I've read recently have turned out to be really great books. Books that made me think a lot about how I work and write software, books that have actually changed my ways of doing these things. When I experience these books having such an effect on me, it is hard for me to resist the temptation to share the knowledge I've attained.

So have made two lists for You to have a look at:

Currently I am reading Andy Hunts book Pragmatic Thinking and Learning, a very interesting book about how our minds work, how to improve our brainfunction, and how to attain higher levels of expertice. I hope to finish reading it in about a week, and then I'll post a more thorough review of it here.

torsdag den 9. juli 2009

How much time do we have?

To night I saw a movie called School Of Life, featuring Ryan Reynolds as an off-the-charts charismatic school teacher. The movie was "above average", but the thing that stuck with me afterwards was this motto Ryan had in the movie. He asked his pupils rhetorically: "How much time do we have?", and he answered the question: "Not a lot!" His point was, that with only a limited time in this life, you better really make every moment count.

Now how does this relate to software development?

Well, my thoughts were along the lines of: Take pride in your work, and make sure you produce high quality software every day.

While this makes sense, I suddenly realized that this motto can be seen as a recommendation of agile development: With only a limited time before the deadline of the project, make sure you spend you time working on the most important things at all times.

This is part of the definition of most agile methodologies, and in my humble opinion, the most significant one. The fact that the customer knows, that we as developers always focus on the customer's top priority tasks, is what it's all about!
That is how we get the customer to buy into the agile way of running projects.
That is how we make sure, that the customer ends up with a system, that works the way the customer wants, and that the end users will enjoy using.
That is how we as vendors will gain customer satisfaction, repeat business and success in the market.

So if you are using a non-agile methodology, I'd say it's about time to begin looking into topics like agile, Scrum, TDD / BDD, etc.

We don't have much time, so we better make it count!

mandag den 29. juni 2009

Working Effectively with Legacy Code - part 2

One of the biggest challenges, when it comes to adding tests to legacy code systems, is dependencies between different parts of the system. Dependencies comes in lots of different flavours, some of which are: Constructor parameters that must be supplied, properties that must be set, globals being referenced from anywhere, external libraries being used, framework APIs being used, databases, and also all kinds of physical devices like discs, printers, etc.

The problem with dependencies are, that if you want to test a class in a way, that isolates that class from anything else, so you can easily detect changes in functionality, the dependencies must be taken out of the picture. If not, a potential failure could be caused not only by the code we touched, but also by anything that code depends upon. You need to be able to construct an object of the class under test in an way, where you are able to control the object's environment completely.

So how do you remove dependencies? Well, it depends ... (pun fully intended)

In the book "Working Effectively with Legacy Code", Michael Feathers includes a wealth of techniques for breaking dependencies - in fact, about the last third of the book is dedicated to this very topic. And the really great thing is, not only does he teach us a lot of techniques, he also attempts to bestowe within us, the wisdom to choose the optimal technique for any specific type of problem and dependency. Let me just give a very few highlights about constructor parameter dependencies here:
  • 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.
A few highlights about references to globals too:
  • 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.

These techniques and many more are explained in the book in crystal clear details, and with example code to match. As I read through the book, I can't help but thinking, that I should have read this book back in 2005, when it was published, because it would have saved me so much pain and anguish by now ... well, in this case, the phrase "better late than never" is very appropriate: These techniques will continue to be valuable for a long time. So no excuses left - Read the book!

søndag den 21. juni 2009

Working Effectively with Legacy Code (WELC)

Well, two weeks went by pretty fast, and I haven't had very much time to myself, so I have still not finished my new Bible, WELC ... however, I've been preaching the subject to several colleagues and members of the development community, and I've received lots of positive feedback. This affirms my belief, that this book will change the way I (and hopefully other developers around me too) works with legacy systems.

In this post I'll dive into one of the concrete techniques from the book, so You get an idea of why I'm so excited about the book. The technique I have chosen is from chapter 6 "I Don't Have Much Time and I Have to Change It" from the book, and it is merely meant as a teaser - I want You to read the book for yourselves and form Your own opinions. I will show more methods soon.

The "Wrap Method" technique.

The main problem you face, when having to add new functionality to a legacy system, wether a bug fix or a new feature, is inadvertently introducing new bugs. Since legacy systems does not have (sufficient) tests, changing code is feeling close to Russian Roulette, only with 5 bullets and 1 empty slot in the revolver, and not the other way around.

The Wrap Method technique allows you to add functionality to existing methods without the risk of introducing new bugs. Sounds like magic, right? Well it isn't, it is just a very straightforward application of encapsulation and separation of concerns.

The idea is, that if you can characterize your change as appending new functionality at the beginning or at the end of an existing method, you create a new method containing the new functionality plus a call to the existing method. Then you swap the names of the existing method and the new method. This means, that every call to the original method suddenly hits the new method, which in turn calls the original method before or after executing the new functionality.

Here is an example. The following method is the one you want to add functionality to:

public void MethodA([lots of parameters])
{
// Hundreds or thousands of lines of complex functionality
}

You want to include a call to another method, MethodB, in MethodA. However MethodA is complex enough as it is. So we add another method, NewMethod:

public void NewMethod([same parameters as MethodA])
{
MethodB([some parameters]);
MethodA([lots of parameters]);
}

Finally we swap the names of MethodA and NewMethod:

public void NewMethod([lots of parameters])
{
// Hundreds or thousands of lines of complex functionality
}

public void MethodA([same parameters as MethodA])
{
MethodB([some parameters]);
NewMethod([lots of parameters]);
}

This way, all calls to the original MethodA now hits the new MethodA, which includes a call to MethodB, and we have not changed a single line of code inside MethodA. So the only potential bugs introduced is in the call to MethodB - quite a bit easier to debug than debugging MethodA, right?

This technique demonstrates one of Michael Feathers' principles: Don't change code without tests to validate your change.

søndag den 7. juni 2009

My very first blog entry

This is my very first blog entry, and I've been putting it off for way too long.

For the last three years, I've been thinking a lot about the way, we build and maintain software. By "we" I mean both the developers at the company I work for, but also in the software development community as a hole. I've been reading a lot of books, and I've attended quite a few conferences, seminars and lectures on software development, and I have finally reached the point, where I feel I'm ready to begin contributing to the subject myself. This blog (On the way to better software) is my first real attempt to give something back to the community, that has taught me so much over the years.

In this blog entry, I want to share my thoughts on the book, I am currently reading: "Working Effectively with Legacy Code" (WELC) by Michael Feathers (check out the link).

To add a little perspective on why this book caught my attention, I'll tell a little about the job, I've had since November 2004. I work at a consulting company / ISV in Denmark, and lately I've been assigned to a product team building one of our products. 

The product was originally built in PowerBuilder about 7 or 8 years ago, but was converted, line for line, to C# by an outsourcing partner 3 years ago. This means that the application architecture was not improved, and whatever oddities were in the original program, is still present today, only magnified by the brutal translation from PowerBuilder to C#.

I was assigned to this project because productivity on the team is going down, the number of hours per bug fix and per change/expansion is rising, and the morale among the developers is suffering. My task is to help turn this project around.

The first thing I did was to have a few hours of brainstorming with the developers on the team. I wanted them to tell me all the things about this project, that felt like a pain. This included build procedures, architecture issues, bug reporting procedures, change request processes, time tracking and much more. This brainstorming session resulted in a list of almost 30 issues, or impediments, that the developers felt were most painful.

The next step is to assign each issue with a severity level and an estimate. I want to indicate which issues are the most harmful ones. The estimates will be qualified guesses made be myself and a few of the most experienced developers on the developement team, and they will indicate which issues will be the quickest to fix. These two numbers together will (hopefully) indentify the "quick wins", which will be started up first.

To get back to WELC, I began reading the book a week ago, and immediately I sensed, that this book will change the way I think about legacy code, and how to handle legacy code. 

First of all, the author defines legacy code as code without tests. Think about this for a minute: You can be writing the cleanest code, using all the best practices of software architecture and of your current development platform. But if you're not writing the tests to verify and document your code, your code becomes legacy code immediately! This means that the next developer looking at your code, will have no way of knowing what your code is supposed to do, other than external documentation of course. The effect is, the next developer will never know if the code is behaving correct or not! This is of course very, very bad!

So we should all be doing TDD, or at least be disciplined enough to write the tests for our code, before we release it to the public.

The focus of WELC however, is not TDD or the likes, but more generally how to improve code quality, bug fix hours, change request hours and morale on legacy code projects. And the key is to add tests. Not tests to cover every line of legacy code, but enough tests to cover the code changes we want to make. In order to do this, code dependencies must be broken, some code will have to be refactored, and all new code must be covered by tests. WELC lists lots and lots of techniques to do this, and the author takes you through very clear examples on how to employ these techniques.

I have not finished reading WELC yet, and I can guarantee, that this will not be the last time I read it. This book will not only help you save sinking projects, but it will make you think about, how you architect your software on "greenfield" projects in the future. This is indeed a very valuable book, and you should read it today rather than tomorrow.

Mikkel Toudal Kristiansen
On the way to better software ...