One of the fascinating things found in nature is the ability of a species to adapt to its changing environment. The canonical example of this is Britain’s Peppered Moth. When newly industrialized Great Britain became polluted in the nineteenth century, slow-growing, light-colored lichens that covered trees died and resulted in a blackening of the trees bark. The impact of this was quite profound: lightly-colored peppered moths, which historically had been well camouflaged and the majority, now found themselves the obvious target of many a hungry bird. Their rare, dark-colored sibling, who had been conspicuous before, now blended into their recently polluted ecosystem. As the birds, changed from eating dark-colored to light-colored moths, the previously common light-colored moth became the minority, and the dynamics of Britain’s moth population changed.
So what do moths have to do with programming? Well, moths in and of themselves are not particularly interesting in this regard, rather how they adapted is. The peppered moth was able to survive a new hostile environment due to a genetic mutation that allowed it to react to the changes around. This ability to react on-the-fly is what a reactive application is all about: an application that reacts to its changing environment by design. Built into its DNA is the ability to:
- React to load
- React to failure
- React to users
We achieve this by the underlying notion of reacting to messages, but more on that later.
Just like the challenging environment of the Peppered Moth, today’s world faces the hurdles of the ever-growing demands of modern computing and it requires competent and efficient solutions. As developers, we must be able to build applications that exhibit the ability to react to these demands. With user expectations of split-second performance, spikes in application load, and data expansion into the petabytes, modern applications must embrace these requirements by incorporating reactive behavior into their DNA.
In the new world, it is not the big fish which eats the small fish, it’s the fast fish which eats the slow fish. —Klaus Schwab
Principles of reactive applications
Sound programming principles such as message-driven, elasticity, resilience and responsiveness are the root in a reactive application’s DNA. Let’s define each of these principles, as defined in the Reactive Manifesto, the blueprint for building reactive applications:
Reacting to messages: Based on asynchronous communication where the design of sender and recipient are not affected by the means of message propagation. As a result, you can design your system in isolation without worrying about how the transmission of messages occurs. Message-driven communication leads to a loosely coupled design that provides scalability, resilience, and responsiveness.
Reacting to load: The system stays responsive under varying workload. Reactive applications can actively scale up and down or scale in and out based upon usage or other metrics utilized by system designers, saving money on unused computing power, but most importantly ensuring the servicing of growing or spiking user base.
Reacting to failure: The system stays responsive in the face of failure. Failure is expected and embraced, and since many systems exist in isolation, a single point of failure remains just that. The system responds appropriately with strategies for restarting or re-provisioning, seamless to the overall systems.
React to users: The system responds promptly if at all possible. Responsiveness is the cornerstone of usability and utility, but more than that, responsiveness means that problems may be detected quickly and dealt with effectively.
Reactive applications are not boilerplate applications and are challenging to build. They are designed to react to changes in their surrounding environment without having to write new code, and that is a hefty task. Additionally they are based on a set of principles and techniques, which are not new, but are just now becoming mainstream. For example, many current applications on the JVM favor frameworks like Spring or Hibernate, while reactive applications tend to favor toolkits such as Akka. Akka is considered both a toolkit and runtime for building highly concurrent, distributed, and resilient, message-driven applications.
Don’t let this new paradigm, with its use of robust toolkits like Akka, give you pause, however. Reactive programming is a very different way of building applications. By embracing the traits listed above, you will be able to solve the complex problems associated with distributed systems, concurrent programming, fault tolerance, and more.
Editor’s note: if you’re a Java developer that wants to start building responsive, resilient, and elastic distributed apps, you’ll want to attend Duncan DeVore and Henrik Engstrom’s Introduction to reactive programming training course at OSCON.
This post is part of our ongoing exploration into learning how to solve programming problems.