Razor Insights

Integrating & Scaling Legacy Systems

Written by Jamie Hinton
Published on
How to take proprietary & legacy systems and make them scale for all your users on all platforms and channels.

We love the challenge of taking legacy, proprietary, disparate and new systems and making them work together.

In the case of legacy or proprietary systems, we are often required to take a system that was only ever intended for internal use and put that functionality in the hands of the customer to allow them to self serve or to push it so that people can access it remotely on a mobile device.

Without the appropriate engineering in place, both the user and the business can suffer as response times slow to crawling pace, data degradation begins to occur, or the system fails completely. These problems generally occur because connectivity to a part of the system is restricted or it simply wasn't designed for high concurrency and load.

Mitigation

To mitigate against this, first we wrap the existing system in an Application Programming Interface (API) so that we can cleanly expose the functionality to alternative interfaces such as a web interface or mobile applications. We also add any necessary business logic to reduce the complexity of the calling interfaces. Within the API we then have the opportunity to apply a software design pattern called “circuit breaker”.

Circuit Breaker Diagram 1

The circuit breaker is introduced between each of the calls to the underlying system and captures errors that occur. These are most commonly internal application errors and network connectivity time outs.

When a pre-defined threshold of errors is encountered in any one section, the circuit is opened and any subsequent calls are handled by delaying a retry and informing the user appropriately.

The circuit then stays open until a fixed duration has elapsed. Once elapsed a small number of requests are allowed through to test if the functionality or connectivity has returned and once positive responses are returned the circuit is then closed. This gives the dependent system or infrastructure time to self heal; something it wouldn't get chance to do under constant load if the circuit breaker wasn't in place.

Circuit Breaker Diagram 2

One of the other benefits of the circuit breaker is that when dependent systems fail - and they do; the entire application isn't taken down. This ensures users have the best possible experience across the entire application.

Real World Use

One of our most recent uses of the circuit breaker pattern was for the integration of a proprietary internal system for a utilities company, South Staffs Water.

For this project we used our own implementation, which we have designed to be less intrusive than other circuit breaker frameworks. Our implementation is fully integrated with Castle Windsor, an Inversion of Control (IOC) container that we often use. This enables us to provide the circuit control at a service level and manage it at an application level rather than a single session. All of this provides better protection of the underlying systems enabling them to self heal.

During the load and capacity testing of the application, we were able to prove our implementation of the circuit breaker by watching it work in real time. As we made the internal system fail, the connection to it was automatically cut until the application was able to verify that it had recovered.

The circuit breaker pattern is just one of the architectural patterns and practices we employ to gain scalability and durability with legacy, proprietary and disparate systems. It isn't always the answer, but when used right it can provide a robust solution to a tricky problem: connecting business critical legacy systems with increasingly demanding customers.

The circuit breaker pattern is described in depth by Michael Nygard in his book Release It!. It's a must read for any developer building applications that expect more than a handful of visitors!